Compare commits
13 Commits
e78228b1b0
...
0e31a6c2ad
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | 0e31a6c2ad | |
Lennart Poettering | bed0b7dfc0 | |
Luca Boccassi | 7143b95552 | |
Frantisek Sumsal | cb713f1696 | |
Zbigniew Jędrzejewski-Szmek | 7f56c26d10 | |
Luca Boccassi | 0cffae953a | |
Lennart Poettering | b47261e5cb | |
Lennart Poettering | 3f8ed9fd96 | |
Lennart Poettering | 18d9cee002 | |
Lennart Poettering | d247f232a8 | |
Lennart Poettering | 4dd055f907 | |
Lennart Poettering | 45250e66cc | |
Lennart Poettering | 97f1c6af8c |
631
NEWS
631
NEWS
|
@ -2,25 +2,147 @@ systemd System and Service Manager
|
|||
|
||||
CHANGES WITH 246 in spe:
|
||||
|
||||
* The various programs included in systemd can now optionally output
|
||||
their log messages on stderr prefixed with a timestamp, controlled by
|
||||
the $SYSTEMD_LOG_TIME environment variable.
|
||||
* The service manager gained basic support for cgroup v2 freezer. Units
|
||||
can now be suspended or resumed either using new systemctl verbs,
|
||||
freeze and thaw respectively, or via D-Bus.
|
||||
|
||||
* PID 1 may now automatically load pre-compiled AppArmor policies from
|
||||
/etc/apparmor/earlypolicy during early boot.
|
||||
|
||||
* The CPUAffinity= setting in service unit files now supports a new
|
||||
special value "numa" that causes the CPU affinity masked to be set
|
||||
based on the NUMA mask.
|
||||
|
||||
* systemd will now log about all left-over processes remaining in a
|
||||
unit when the unit is stopped. It will now warn about services using
|
||||
KillMode=none, as this is generally an unsafe thing to make use of.
|
||||
|
||||
* Two new unit file settings
|
||||
ConditionPathIsEncrypted=/AssertPathIsEncrypted= have been
|
||||
added. They may be used to check whether a specific file system path
|
||||
resides on a block device that is encrypted on the block level
|
||||
(i.e. using dm-crypt/LUKS).
|
||||
|
||||
* Another pair of new settings ConditionEnvironment=/AssertEnvironment=
|
||||
has been added that may be used for simple environment checks. This
|
||||
is particularly useful when passing in environment variables from a
|
||||
container manager (or from PAM in case of the systemd --user
|
||||
instance).
|
||||
|
||||
* .service unit files now accept a new setting CoredumpFilter= which
|
||||
allows configuration of the memory sections coredumps of the
|
||||
service's processes shall include.
|
||||
|
||||
* .mount units gained a new ReadWriteOnly= boolean option. If set
|
||||
it will not be attempted to mount a file system read-only if mounting
|
||||
in read-write mode doesn't succeed. An option x-systemd.rw-only is
|
||||
available in /etc/fstab to control the same.
|
||||
|
||||
* .socket units gained a new boolean setting PassPacketInfo=. If
|
||||
enabled, the kernel will attach additional per-packet metadata to all
|
||||
packets read from the socket, as ancillary message. This controls the
|
||||
IP_PKTINFO, IPV6_RECVPKTINFO, NETLINK_PKTINFO socket options,
|
||||
depending on socket type.
|
||||
|
||||
* .service units gained a new setting RootHash= which may be used to
|
||||
specify the root hash for verity enabled disk images which are
|
||||
specified in RootImage=. RootVerity= may be used to specify a path to
|
||||
the Verity data matching a RootImage= file system. (The latter is
|
||||
only useful for images that do not contain the Verity data embedded
|
||||
into the same image that carries a GPT partition table following the
|
||||
Discoverable Partition Specification). Similarly, systemd-nspawn
|
||||
gained a new switch --verity-data= that takes a path to a file with
|
||||
the verity data of the disk image supplied in --image=, if the image
|
||||
doesn't contain the verity data itself.
|
||||
|
||||
* .service units gained a new setting RootHashSignature= which takes
|
||||
either a base64 encoded PKCS#7 signature of the root hash specified
|
||||
with RootHash=, or a path to a file to read the signature from. This
|
||||
allows validation of the root hash against public keys available in
|
||||
the kernel keyring, and is only supported on recent kernels
|
||||
(>= 5.4)/libcryptsetup (>= 2.30). A similar switch has been added to
|
||||
systemd-nspawn and systemd-dissect (--root-hash-sig=). Support for
|
||||
this mechanism has also been added to systemd-veritysetup.
|
||||
|
||||
* .service unit files gained two new options
|
||||
TimeoutStartFailureMode=/TimeoutStopFailureMode= that may be used to
|
||||
tune behaviour if a start or stop timeout is hit, i.e. whether to
|
||||
terminate the service with SIGTERM, SIGABRT or SIGKILL.
|
||||
|
||||
* Most options in systemd that accept hexadecimal values prefixed with
|
||||
0x in additional to the usual decimal notation now also support octal
|
||||
notation when the 0o prefix is used and binary notation if the 0b
|
||||
prefix is used.
|
||||
|
||||
* Unit files, tmpfiles.d/ snippets, sysusers.d/ snippets and other
|
||||
configuration files that support specifier expansion learnt six new
|
||||
specifiers: %a resolves to the current architecture, %o/%w/%B/%W
|
||||
resolve to the various ID fields from /etc/os-release, %l resolves to
|
||||
the "short" hostname of the system, i.e. the hostname configured in
|
||||
the kernel truncated at the first dot.
|
||||
|
||||
* Support for the .include syntax in unit files has been removed. The
|
||||
concept has been obsolete for 6 years and we started warning about
|
||||
its pending removal 2 years ago (also see NEWS file below). It's
|
||||
finally gone now.
|
||||
|
||||
* StandardError= and StandardOutput= in unit files no longer support
|
||||
the "syslog" and "syslog-console" switches. They were long removed
|
||||
from the documentation, but will now result in warnings when used,
|
||||
and be converted to "journal" and "journal+console" automatically.
|
||||
|
||||
* A new kernel command line option systemd.hostname= has been added
|
||||
that allows controlling the hostname that is initialized early during
|
||||
boot.
|
||||
|
||||
* A kernel command line option "udev.blockdev_read_only" has been
|
||||
added. If specified all hardware block devices that show up are
|
||||
immediately marked as read-only by udev. This option is useful for
|
||||
making sure that a specific boot under no circumstances modifies data
|
||||
on disk. Use "blockdev --setrw" to undo the effect of this, per
|
||||
device.
|
||||
|
||||
* A new boolean kernel command line option systemd.swap= has been
|
||||
added, which may be used to turn off automatic activation of swap
|
||||
devices, as listed in /etc/fstab.
|
||||
devices listed in /etc/fstab.
|
||||
|
||||
* The CPUAffinity= setting in service unit files now supports a new
|
||||
special value "numa". If used, the NUMA mask is copied into the CPU
|
||||
affinity mask.
|
||||
* New kernel command line options systemd.condition-needs-update= and
|
||||
systemd.condition-first-boot= have been added, which override the
|
||||
result of the ConditionNeedsUpdate= and ConditionFirstBoot=
|
||||
conditions.
|
||||
|
||||
* The man pages for the sd-bus and sd-hwdb APIs have been completed.
|
||||
* A new kernel command line option systemd.clock-usec= has been added
|
||||
that allows setting the system clock to the specified time in µs
|
||||
since Jan 1st, 1970 early during boot. This is in particular useful
|
||||
in order to make test cases more reliable.
|
||||
|
||||
* networkctl gained the new "forcerenew" command for forcing all DHCP
|
||||
server clients to renew their lease. The interface "status" output
|
||||
will now show numerous additional fields of information about an
|
||||
interface. There are new "up" and "down" commands to bring specific
|
||||
interfaces up or down.
|
||||
* The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
|
||||
systemd-coredump to save core files for suid processes. When saving
|
||||
the core file, systemd-coredump will use the effective uid and gid of
|
||||
the process that faulted.
|
||||
|
||||
* The /sys/module/kernel/parameters/crash_kexec_post_notifiers file is
|
||||
now automatically set to "Y" at boot, in order to enable pstore
|
||||
generation for collection with systemd-pstore.
|
||||
|
||||
* A new 'hwdb' file has been added that collects information about PCI
|
||||
and USB devices that correctly support auto-suspend, on top of the
|
||||
databases for this we import from the ChromiumOS project. If you have
|
||||
a device that supports auto-suspend correctly and where it should be
|
||||
enabled by default, please submit a patch that adds it to the
|
||||
database (see /usr/lib/udev/hwdb.d/60-autosuspend.hwdb).
|
||||
|
||||
* systemd-udevd gained new configuration option timeout_signal= as well
|
||||
as corresponding kernel command line option udev.timeout_signal=.
|
||||
The option can be used to configure the UNIX signal that the main
|
||||
daemon sends to the worker processes on timeout. Setting the signal
|
||||
to SIGABRT is useful for debugging.
|
||||
|
||||
* .link files managed by systemd-udevd gained options RxFlowControl=,
|
||||
TxFlowControl=, AutoNegotiationFlowControl= in the [Link] section, in
|
||||
order to configure various flow control parameters. They also gained
|
||||
RxMiniBufferSize= and RxJumboBufferSize= in order to configure jumbo
|
||||
frame ring buffer sizes.
|
||||
|
||||
* systemd-networkd's [IPv6Prefix] section in .network files gained a
|
||||
new boolean setting Assign=. If enabled an address from the prefix is
|
||||
|
@ -28,8 +150,7 @@ CHANGES WITH 246 in spe:
|
|||
|
||||
* systemd-networkd's [Network] section gained a new setting
|
||||
IPv6PDSubnetId= that allows explicit configuration of the preferred
|
||||
subnet that networkd's Prefix Delegation logic assigns to an
|
||||
interfaces.
|
||||
subnet that networkd's Prefix Delegation logic assigns to interfaces.
|
||||
|
||||
* systemd-networkd gained support for configuring the HTB queuing
|
||||
discipline in the [HierarchyTokenBucket] and
|
||||
|
@ -50,12 +171,6 @@ CHANGES WITH 246 in spe:
|
|||
traffic). DataBitRate=, DataSamplePoint=, FDMode=, FDNonISO= have
|
||||
been added to configure various CAN-FD aspects.
|
||||
|
||||
* .link files managed by systemd-udevd gained options RxFlowControl=,
|
||||
TxFlowControl=, AutoNegotiationFlowControl= in the [Link] section, in
|
||||
order to configure various flow control parameters. They also gained
|
||||
RxMiniBufferSize= and RxJumboBufferSize= in order to configure jumbo
|
||||
frame ring buffer sizes.
|
||||
|
||||
* systemd-networkd's [DHCPv6] section gained a new WithoutRA= boolean
|
||||
setting. If enabled, DHCPv6 will be attempted right-away without
|
||||
requiring an Router Advertisement packet suggesting it
|
||||
|
@ -83,6 +198,35 @@ CHANGES WITH 246 in spe:
|
|||
Description"). Support for "MUD" URLs was also added to the LLDP
|
||||
stack, configurable in the [LLDP] section in .network files.
|
||||
|
||||
* systemd-networkd's .netdev files now support a new setting
|
||||
VLANProtocol= in the [Bridge] section that allows configuration of
|
||||
the VLAN protocol to use.
|
||||
|
||||
* systemd-networkd supports a new Group= setting in the [Link] section
|
||||
of the .network files, to control the link group.
|
||||
|
||||
* A new default .network file is now shipped that matches TUN/TAP
|
||||
devices that begin with "vt-" in their name. Such interfaces will
|
||||
have IP routing onto the host links set up automatically. This is
|
||||
supposed to be used by VM managers to trivially acquire a network
|
||||
interface which is fully set up for host communication, simply by
|
||||
carefully picking an interface name to use.
|
||||
|
||||
* A new boolean option AssignAcquiredDelegatedPrefixAddress= has been
|
||||
added to the [DHCPv6] section of .network files. If enabled (which is
|
||||
the default) an address from any acquired delegated prefix is
|
||||
automatically chosen and assigned to the interface.
|
||||
|
||||
* The BlackList= settings in .network files' [DHCPv4] and
|
||||
[IPv6AcceptRA] sections have been renamed DenyList=. The old names
|
||||
are still understood to provide compatibility.
|
||||
|
||||
* networkctl gained the new "forcerenew" command for forcing all DHCP
|
||||
server clients to renew their lease. The interface "status" output
|
||||
will now show numerous additional fields of information about an
|
||||
interface. There are new "up" and "down" commands to bring specific
|
||||
interfaces up or down.
|
||||
|
||||
* systemd-resolved's DNS= configuration option now optionally accepts
|
||||
DNS server addresses suffixed by "#" followed by a host name. If
|
||||
used, the DNS-over-TLS certificate is validated to match the
|
||||
|
@ -94,93 +238,6 @@ CHANGES WITH 246 in spe:
|
|||
|
||||
* systemd-resolved's DNS-over-TLS support gained SNI validation.
|
||||
|
||||
* The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
|
||||
systemd-coredump to save core files for suid processes. When saving
|
||||
the core file, systemd-coredump will use the effective uid and gid of
|
||||
the process that faulted.
|
||||
|
||||
* "systemctl list-units" and "systemctl list-machines" no longer hide
|
||||
their first output column with --no-legend. To hide the first column,
|
||||
use --plain.
|
||||
|
||||
* The service manager gained basic support for cgroup v2 freezer. Units
|
||||
can now be suspended or resumed either using new systemctl verbs,
|
||||
freeze and thaw respectively, or via D-Bus.
|
||||
|
||||
* systemd-udevd gained new configuration option timeout_signal= as well
|
||||
as corresponding kernel command line option udev.timeout_signal=.
|
||||
The option can be used to configure the UNIX signal that the main
|
||||
daemon sends to the worker processes on timeout.
|
||||
|
||||
* A new sd-path.h API has been added to libsystemd. It provides a
|
||||
simple API for retrieving various search paths and primary
|
||||
directories for various resources.
|
||||
|
||||
* The sd-bus API gained a number of convenience functions that take
|
||||
va_list arguments rather than "...". For example, there's now
|
||||
sd_bus_call_methodv() to match sd_bus_call_method(). Previously,
|
||||
these were missing since the calls are convenience calls only and
|
||||
could be put together from the more low-level functions they build
|
||||
on.
|
||||
|
||||
* sd-bus vtable entries learnt a new flag SD_BUS_VTABLE_ABSOLUTE_OFFSET
|
||||
which alters how the userdata pointer to pass to the callbacks is
|
||||
determined. If the flag is set the offset field is converted as-is
|
||||
into a pointer, without adding it to the object pointer the vtable is
|
||||
associated with.
|
||||
|
||||
* sd-bus now exposes four new functions:
|
||||
sd_bus_interface_name_is_valid() + sd_bus_service_name_is_valid() +
|
||||
sd_bus_member_name_is_valid() + sd_bus_object_path_is_valid() will
|
||||
validate strings to check if they qualify as various D-Bus concepts.
|
||||
|
||||
* The sd-bus API gained the SD_BUS_METHOD_WITH_ARGS(),
|
||||
SD_BUS_METHOD_WITH_ARGS_OFFSET() and SD_BUS_SIGNAL_WITH_ARGS() macros
|
||||
that simplify adding argument names to D-Bus methods and signals.
|
||||
|
||||
* systemctl gained a new "-P" switch that is a shortcut for "--value
|
||||
--property=…".
|
||||
|
||||
* The expectations on user/group name syntax are now documented in
|
||||
detail; documentation how classic home directories may be converted
|
||||
into home directories managed by homed has been added; documentation
|
||||
regarding integration of homed/userdb functionality in desktops has
|
||||
been added:
|
||||
|
||||
https://systemd.io/USER_NAMES
|
||||
https://systemd.io/CONVERTING_TO_HOMED
|
||||
https://systemd.io/USERDB_AND_DESKTOPS
|
||||
|
||||
* systemd-run gained a new switch --slice-inherit. If specified the
|
||||
unit it generates is placed in the same slice as the systemd-run
|
||||
process itself.
|
||||
|
||||
* service unit files now accept a new setting CoredumpFilter= which
|
||||
allows configuration of the memory sections coredumps of the
|
||||
service's processes shall include.
|
||||
|
||||
* coredumpctl gained a new --file= switch, matching the same one in
|
||||
journalctl: a specific journal file may be specified to read the
|
||||
coredump data from.
|
||||
|
||||
* Various D-Bus APIs of systemd daemons now have man pages that
|
||||
document the methods, signals and properties.
|
||||
|
||||
* journald.conf gained a new boolean setting Audit= that may be used to
|
||||
control whether systemd-journald will enable audit during
|
||||
initialization.
|
||||
|
||||
* A new default .network file is now shipped that matches TUN/TAP
|
||||
devices that begin with "vt-" in their name. Such interfaces will
|
||||
have IP routing onto the host links set up automatically. This is
|
||||
supposed to be used by VM managers to trivially acquire a network
|
||||
interface which is fully set up for host communication, simply by
|
||||
carefully picking an interface name to use.
|
||||
|
||||
* All D-Bus services shipped in systemd now implement the generic
|
||||
LogControl1 D-Bus API which allows clients to change log level +
|
||||
target of the service during runtime.
|
||||
|
||||
* systemd-nspawn's --resolv-conf= switch gained a number of new
|
||||
supported values. Specifically, options starting with "replace-" are
|
||||
like those prefixed "copy-" but replace any existing resolv.conf
|
||||
|
@ -188,80 +245,82 @@ CHANGES WITH 246 in spe:
|
|||
propagate other flavours of resolv.conf into the container (as
|
||||
defined by systemd-resolved).
|
||||
|
||||
* systemd-binfmt gained a new switch --unregister for unregistering all
|
||||
registered entries at once. This is now invoked automatically at
|
||||
shutdown, so that binary formats registered with the "F" flag will
|
||||
not block clean file system unmounting.
|
||||
* The various programs included in systemd can now optionally output
|
||||
their log messages on stderr prefixed with a timestamp, controlled by
|
||||
the $SYSTEMD_LOG_TIME environment variable.
|
||||
|
||||
* Unit files, tmpfiles.d/ snippets, sysusers.d/ snippets and other
|
||||
configuration files that support specifier expansion learnt six new
|
||||
specifiers: %a resolves to the current architecture, %o/%w/%B/%W
|
||||
resolve to the various ID fields from /etc/os-release, %l resolves to
|
||||
the "short" hostname of the system, i.e. the kernel configured
|
||||
hostname, truncated at the first dot.
|
||||
* systemctl gained a new "-P" switch that is a shortcut for "--value
|
||||
--property=…".
|
||||
|
||||
* systemd-notify's --pid= switch gained new values: "parent", "self",
|
||||
"auto" for controlling which PID to send to the service manager: the
|
||||
systemd-notify process' PID, or the one of the process invoking it.
|
||||
* "systemctl list-units" and "systemctl list-machines" no longer hide
|
||||
their first output column with --no-legend. To hide the first column,
|
||||
use --plain.
|
||||
|
||||
* When sending a file descriptor (fd) to the service manager to keep
|
||||
track of, using the sd_notify() mechanism, a new parameter FDPOLL=0
|
||||
may be specified. If passed the service manager will refrain from
|
||||
poll()ing on the file descriptor. Traditionally (and when the
|
||||
parameter is not specified), the service manager will poll it for
|
||||
POLLHUP or POLLERR events, and immediately close the fds in that
|
||||
case.
|
||||
* "systemctl reboot" takes the option "--reboot-argument=".
|
||||
The optional positional argument to "systemctl reboot" is now
|
||||
being deprecated in favor of this option.
|
||||
|
||||
* A new call sd_notify_barrier() has been added to the sd-daemon.h
|
||||
API. The call will block until all previously sent sd_notify()
|
||||
messages have been processed by the service manager. This is useful
|
||||
to remove races caused by a process already having disappeared at the
|
||||
time a notification message is processed by the service manager,
|
||||
making correct attribution impossible. The systemd-notify tool will
|
||||
now make use of this call implicitly, but this can be turned off again
|
||||
via the new --no-block switch.
|
||||
* systemd-run gained a new switch --slice-inherit. If specified the
|
||||
unit it generates is placed in the same slice as the systemd-run
|
||||
process itself.
|
||||
|
||||
* systemd-logind's Session bus object learnt a new method call
|
||||
SetType() for temporarily updating the session type of an already
|
||||
allocated session. This is useful for upgrading tty sessions to
|
||||
graphical ones once a compositor is invoked.
|
||||
* systemd-journald gained support for zstd compression of large fields
|
||||
in journal files. The hash tables in journal files have been hardened
|
||||
against hash collisions. This is an incompatible change and means
|
||||
that journal files created with new systemd versions are not readable
|
||||
with old versions. If the $SYSTEMD_JOURNAL_KEYED_HASH boolean
|
||||
environment variable for systemd-journald.service is set to 0 this
|
||||
new hardening functionality may be turned off, so that generated
|
||||
journal files remain compatible with older journalctl
|
||||
implementations.
|
||||
|
||||
* .mount units gained a new ReadWriteOnly= boolean option. If set
|
||||
it will not be attempted to mount a file system read-only if mounting
|
||||
in read-write mode doesn't succeed. An option x-systemd.rw-only is
|
||||
available in /etc/fstab to control the same.
|
||||
* journalctl will now include a clickable link in the default output for
|
||||
each log message for which an URL with further documentation is
|
||||
known. This is only supported on terminal emulators that support
|
||||
clickable hyperlinks, and is turned off if a pager is used (since
|
||||
"less" still doesn't support hyperlinks,
|
||||
unfortunately). Documentation URLs may be included in log messages
|
||||
either by including a DOCUMENTATION= journal field in it, or by
|
||||
associating a journal message catalog entry with the log message's
|
||||
MESSAGE_ID, which then carries a "Documentation:" tag.
|
||||
|
||||
* coredumps collected by systemd-coredump may now be compressed using
|
||||
the zstd algorithm.
|
||||
* journald.conf gained a new boolean setting Audit= that may be used to
|
||||
control whether systemd-journald will enable audit during
|
||||
initialization.
|
||||
|
||||
* when systemd-journald's log stream is broken up into multiple lines
|
||||
because the PID of the sender changed this is indicated in the
|
||||
generated log records via the _LINE_BREAK=pid-change field.
|
||||
|
||||
* journalctl's "-o cat" output mode will now show one or more journal
|
||||
fields specified with --output-fields= instead of unconditionally
|
||||
MESSAGE=. This is useful to retrieve a very specific set of fields
|
||||
without any decoration.
|
||||
|
||||
* coredumpctl gained a new --file= switch, matching the same one in
|
||||
journalctl: a specific journal file may be specified to read the
|
||||
coredump data from.
|
||||
|
||||
* coredumps collected by systemd-coredump may now be compressed using
|
||||
the zstd algorithm.
|
||||
|
||||
* systemd-binfmt gained a new switch --unregister for unregistering all
|
||||
registered entries at once. This is now invoked automatically at
|
||||
shutdown, so that binary formats registered with the "F" flag will
|
||||
not block clean file system unmounting.
|
||||
|
||||
* systemd-notify's --pid= switch gained new values: "parent", "self",
|
||||
"auto" for controlling which PID to send to the service manager: the
|
||||
systemd-notify process' PID, or the one of the process invoking it.
|
||||
|
||||
* systemd-logind's Session bus object learnt a new method call
|
||||
SetType() for temporarily updating the session type of an already
|
||||
allocated session. This is useful for upgrading tty sessions to
|
||||
graphical ones once a compositor is invoked.
|
||||
|
||||
* systemd-socket-proxy gained a new switch --exit-idle-time= for
|
||||
configuring an exit-on-idle time.
|
||||
|
||||
* systemd-homed's LUKS backend gained the ability to discard empty file
|
||||
system blocks automatically when the user logs out. This is enabled
|
||||
by default to ensure that home directories take minimal space when
|
||||
logged out but get full size guarantees when logged in. This may be
|
||||
controlled with the new --luks-offline-discard= switch to homectl.
|
||||
|
||||
* If systemd-homed detects that /home/ is encrypted as a whole it will
|
||||
now default to the directory or subvolume backends instead of the
|
||||
LUKS backend, in order to avoid double encryption. The default
|
||||
storage and file system may now be configured explicitly, too, via
|
||||
the new /etc/systemd/homed.conf configuration file.
|
||||
|
||||
* when systemd-journald's log stream is broken up into multiple lines
|
||||
because the PID of the sender changed this is indicated in the
|
||||
generated log records via the _LINE_BREAK=pid-change field.
|
||||
|
||||
* systemd-networkd's .netdev files now support a new setting
|
||||
VLANProtocol= in the [Bridge] section that allows configuration of
|
||||
the VLAN protocol to use.
|
||||
|
||||
* systemd-repart's --empty= setting gained a new value "create". If
|
||||
specified a new empty regular disk image file is created under the
|
||||
specified name. Its size may be specified with the new --size=
|
||||
|
@ -279,43 +338,17 @@ CHANGES WITH 246 in spe:
|
|||
* systemd-repart's Label= setting now support the usual, simple
|
||||
specifier expansion.
|
||||
|
||||
* StandardError= and StandardOutput= in unit files no longer support
|
||||
the "syslog" and "syslog-console" switches. They were long removed
|
||||
from the documentation, but will now result in warnings when used,
|
||||
and be converted to "journal" and "journal+console" automatically.
|
||||
* systemd-homed's LUKS backend gained the ability to discard empty file
|
||||
system blocks automatically when the user logs out. This is enabled
|
||||
by default to ensure that home directories take minimal space when
|
||||
logged out but get full size guarantees when logged in. This may be
|
||||
controlled with the new --luks-offline-discard= switch to homectl.
|
||||
|
||||
* systemd-networkd supports a new Group= setting in the [Link] section
|
||||
of the .network files, to control the link group.
|
||||
|
||||
* Two new unit file settings
|
||||
ConditionPathIsEncrypted=/AssertPathIsEncrypted= have been
|
||||
added. They may be used to check whether a specific file system path
|
||||
resides on a block device that is encrypted on the block level
|
||||
(i.e. using dm-crypt/LUKS).
|
||||
|
||||
* Another pair of new settings ConditionEnvironment=/AssertEnvironment=
|
||||
has been added that may be used for simple environment checks. This
|
||||
is particularly useful when passing in environment variables from a
|
||||
container manager (or from PAM in case of the systemd --user
|
||||
instance).
|
||||
|
||||
* The /sys/module/kernel/parameters/crash_kexec_post_notifiers file is
|
||||
now automatically set to "Y" at boot, in order to enable pstore
|
||||
generation for collection with systemd-pstore.
|
||||
|
||||
* New kernel command line options systemd.condition-needs-update= and
|
||||
systemd.condition-first-boot= have been added, which override the
|
||||
result of the ConditionNeedsUpdate= and ConditionFirstBoot=
|
||||
conditions.
|
||||
|
||||
* A new kernel command line option systemd.clock-usec= has been added
|
||||
that allows setting the system clock to the specified time in µs
|
||||
since Jan 1st, 1970 early during boot. This is in particular useful
|
||||
in order to make test cases more reliable.
|
||||
|
||||
* A new kernel command line option systemd.hostname= has been added
|
||||
that allows controlling the hostname that is initialized early during
|
||||
boot.
|
||||
* If systemd-homed detects that /home/ is encrypted as a whole it will
|
||||
now default to the directory or subvolume backends instead of the
|
||||
LUKS backend, in order to avoid double encryption. The default
|
||||
storage and file system may now be configured explicitly, too, via
|
||||
the new /etc/systemd/homed.conf configuration file.
|
||||
|
||||
* The /etc/crypttab tmp option now optionally takes an argument
|
||||
selecting the file system to use. Moreover, the default is now
|
||||
|
@ -338,6 +371,9 @@ CHANGES WITH 246 in spe:
|
|||
/etc/cryptsetup-keys.d/<volume>.key and
|
||||
/run/cryptsetup-keys.d/<volume>.key, if any of these files exist.
|
||||
|
||||
* systemd-cryptsetup may now activate Microsoft BitLocker volumes via
|
||||
/etc/crypttab, during boot.
|
||||
|
||||
* logind.conf gained a new RuntimeDirectoryInodesMax= setting to
|
||||
control the inode limit for the per-user $XDG_RUNTIME_DIR tmpfs
|
||||
instance.
|
||||
|
@ -352,121 +388,12 @@ CHANGES WITH 246 in spe:
|
|||
set the /etc/kernel/cmdline file of an OS image.
|
||||
|
||||
* A new generator systemd-xdg-autostart-generator has been added. It
|
||||
automatically generates systemd unit files from XDG autostart
|
||||
.desktop files, and is useful for allowing systemd to manage services
|
||||
defined that way safely and automatically.
|
||||
generates systemd unit files from XDG autostart .desktop files, and
|
||||
may be used to let the systemd user instance manage services that are
|
||||
started automatically as part of the desktop session.
|
||||
|
||||
* systemd will now log about all left-over processes remaining in a
|
||||
unit when the unit is stopped. It will now warn about services using
|
||||
KillMode=none, as this is generally an unsafe thing to make use of.
|
||||
|
||||
* .socket units gained a new boolean setting PassPacketInfo=. If
|
||||
enabled, the kernel will attach additional per-packet metadata to all
|
||||
packets read from the socket, as ancillary message. This controls the
|
||||
IP_PKTINFO, IPV6_RECVPKTINFO, NETLINK_PKTINFO socket options,
|
||||
depending on socket type.
|
||||
|
||||
* A new boolean option AssignAcquiredDelegatedPrefixAddress= has been
|
||||
added to the [DHCPv6] section of .network files. If enabled (which is
|
||||
the default) an address from any acquired delegated prefix is
|
||||
automatically chosen and assigned to the interface.
|
||||
|
||||
* "systemctl reboot" takes the option "--reboot-argument=".
|
||||
The optional positional argument to "systemctl reboot" is now
|
||||
being deprecated in favor of this option.
|
||||
|
||||
* Support for the .include syntax in unit files has been removed. The
|
||||
concept has been obsolete for 6 years and we started warning about
|
||||
its pending removal 2 years ago (also see NEWS file below). It's
|
||||
finally gone now.
|
||||
|
||||
* The BlackList= settings in .network files' [DHCPv4] and
|
||||
[IPv6AcceptRA] sections have been renamed DenyList=. The old names
|
||||
are still understood to provide compatibility.
|
||||
|
||||
* systemd-journald gained support for zstd compression of large fields
|
||||
in journal files. The hash tables in journal files have been hardened
|
||||
against hash collisions. This is an incompatible change and means
|
||||
that journal files created with new systemd versions are not readable
|
||||
with old versions. If the $SYSTEMD_JOURNAL_KEYED_HASH boolean
|
||||
environment variable for systemd-journald.service is set to 0 this
|
||||
new hardening functionality may be turned off, so that generated
|
||||
journal files remain compatible with older journalctl
|
||||
implementations.
|
||||
|
||||
* Documentation for the on-disk Journal file format has been updated
|
||||
and has now moved to:
|
||||
|
||||
https://systemd.io/JOURNAL_FILE_FORMAT
|
||||
|
||||
* systemd service units gained a new setting RootHash= which may be
|
||||
used to specify the root hash for verity enabled disk images which
|
||||
are specified in RootImage=. RootVerity= may be used to specify a
|
||||
path to the Verity data matching a RootImage= file system. (The
|
||||
latter is only useful for images that do not contain the Verity data
|
||||
embedded into the same image that carries a GPT partition table
|
||||
following the Discoverable Partition Specification). Similar,
|
||||
systemd-nspawn gained a new switch --verity-data= that takes a path
|
||||
to a file with the verity data of the disk image supplied in
|
||||
--image=, if the image doesn't contain the verity data itself.
|
||||
|
||||
* systemd service units gained a new setting RootHashSignature= which
|
||||
takes either a base64 encoded PKCS#7 signature of the root hash
|
||||
specified with RootHash=, or a path to a file to read the signature
|
||||
from. This allows validation of the root hash against public keys
|
||||
available in the kernel keyring, and is only supported on recent
|
||||
kernels (>= 5.4)/libcryptsetup (>= 2.30). A similar switch has been
|
||||
added to systemd-nspawn and systemd-dissect
|
||||
(--root-hash-sig=). Support for this mechanism has also been added to
|
||||
systemd-veritysetup.
|
||||
|
||||
* A new 'hwdb' file has been added that collects information about PCI
|
||||
and USB devices that correctly support auto-suspend, on top of the
|
||||
databases for this we import from the ChromiumOS project. If you have
|
||||
a device that supports auto-suspend correctly and where it should be
|
||||
enabled by default, please submit a patch that adds it to the
|
||||
database (see hwdb.d/60-autosuspend.hwdb).
|
||||
|
||||
* The service manager (PID1) gained a new D-Bus method call
|
||||
SetShowStatus() which may be used to control whether it shall show
|
||||
boot-time status output on the console. This method has a similar
|
||||
effect to sending SIGRTMIN+20/SIGRTMIN+21 to PID 1.
|
||||
|
||||
* PID 1 may now automatically load pre-compiled AppArmor policies from
|
||||
/etc/apparmor/earlypolicy during early boot.
|
||||
|
||||
* systemd-cryptsetup may now activate Microsoft BitLocker volumes via
|
||||
/etc/crypttab, during boot.
|
||||
|
||||
* systemd service unit files gained two new options
|
||||
TimeoutStartFailureMode=/TimeoutStopFailureMode= that may be used to
|
||||
tune behaviour if a start or stop timeout is hit, i.e. whether to
|
||||
terminate the service with SIGTERM, SIGABRT or SIGKILL.
|
||||
|
||||
* A kernel command line option "udev.blockdev_read_only" has been
|
||||
added. If specified all hardware block devices that show up are
|
||||
immediately marked as read-only by udev. This option is useful for
|
||||
making sure that a specific boot under no circumstances modifies data
|
||||
on disk. Use "blockdev --setrw" to undo the effect of this, per
|
||||
device.
|
||||
|
||||
* Most options in systemd that accept hexadecimal values prefixed with
|
||||
0x in additional to the usual decimal notation now also support octal
|
||||
notation when he 0o prefix is used and binary notation if the 0b
|
||||
prefix is used.
|
||||
|
||||
* "booctl" gained a new verb "reboot-to-firmware" that may be used
|
||||
to query and change the firmware's reboot into firmware setup flag.
|
||||
|
||||
* journalctl will now include a clickable link in the default output for
|
||||
each log message for which an URL with further documentation is
|
||||
known. This is only supported on terminal emulators that support
|
||||
clickable hyperlinks, and is turned off if a pager is used (since
|
||||
"less" still doesn't support hyperlinks,
|
||||
unfortunately). Documentation URLs may be included in log messages
|
||||
either by including a DOCUMENTATION= journal field in it, or by
|
||||
associating a journal message catalog entry with the log message's
|
||||
MESSAGE_ID, which then carries a "Documentation:" tag.
|
||||
* "bootctl" gained a new verb "reboot-to-firmware" that may be used
|
||||
to query and change the firmware's 'reboot into firmware' setup flag.
|
||||
|
||||
* systemd-firstboot gained a new switch --kernel-command-line= that may
|
||||
be used to initialize the /etc/kernel/cmdline file of the image. It
|
||||
|
@ -478,6 +405,78 @@ CHANGES WITH 246 in spe:
|
|||
specified on the command line (by default, the tool will not override
|
||||
what has already been set before, i.e. is purely incremental).
|
||||
|
||||
* A new sd-path.h API has been added to libsystemd. It provides a
|
||||
simple API for retrieving various search paths and primary
|
||||
directories for various resources.
|
||||
|
||||
* A new call sd_notify_barrier() has been added to the sd-daemon.h
|
||||
API. The call will block until all previously sent sd_notify()
|
||||
messages have been processed by the service manager. This is useful
|
||||
to remove races caused by a process already having disappeared at the
|
||||
time a notification message is processed by the service manager,
|
||||
making correct attribution impossible. The systemd-notify tool will
|
||||
now make use of this call implicitly, but this can be turned off again
|
||||
via the new --no-block switch.
|
||||
|
||||
* When sending a file descriptor (fd) to the service manager to keep
|
||||
track of, using the sd_notify() mechanism, a new parameter FDPOLL=0
|
||||
may be specified. If passed the service manager will refrain from
|
||||
poll()ing on the file descriptor. Traditionally (and when the
|
||||
parameter is not specified), the service manager will poll it for
|
||||
POLLHUP or POLLERR events, and immediately close the fds in that
|
||||
case.
|
||||
|
||||
* The service manager (PID1) gained a new D-Bus method call
|
||||
SetShowStatus() which may be used to control whether it shall show
|
||||
boot-time status output on the console. This method has a similar
|
||||
effect to sending SIGRTMIN+20/SIGRTMIN+21 to PID 1.
|
||||
|
||||
* The sd-bus API gained a number of convenience functions that take
|
||||
va_list arguments rather than "...". For example, there's now
|
||||
sd_bus_call_methodv() to match sd_bus_call_method(). Those calls make
|
||||
it easier to build wrappers that accept variadic arguments and want
|
||||
to pass a ready va_list structure to sd-bus.
|
||||
|
||||
* sd-bus vtable entries can have a new SD_BUS_VTABLE_ABSOLUTE_OFFSET
|
||||
flag which alters how the userdata pointer to pass to the callbacks
|
||||
is determined. When the flag is set, the offset field is converted
|
||||
as-is into a pointer, without adding it to the object pointer the
|
||||
vtable is associated with.
|
||||
|
||||
* sd-bus now exposes four new functions:
|
||||
sd_bus_interface_name_is_valid() + sd_bus_service_name_is_valid() +
|
||||
sd_bus_member_name_is_valid() + sd_bus_object_path_is_valid() will
|
||||
validate strings to check if they qualify as various D-Bus concepts.
|
||||
|
||||
* The sd-bus API gained the SD_BUS_METHOD_WITH_ARGS(),
|
||||
SD_BUS_METHOD_WITH_ARGS_OFFSET() and SD_BUS_SIGNAL_WITH_ARGS() macros
|
||||
that simplify adding argument names to D-Bus methods and signals.
|
||||
|
||||
* The man pages for the sd-bus and sd-hwdb APIs have been completed.
|
||||
|
||||
* Various D-Bus APIs of systemd daemons now have man pages that
|
||||
document the methods, signals and properties.
|
||||
|
||||
* The expectations on user/group name syntax are now documented in
|
||||
detail; documentation how classic home directories may be converted
|
||||
into home directories managed by homed has been added; documentation
|
||||
regarding integration of homed/userdb functionality in desktops has
|
||||
been added:
|
||||
|
||||
https://systemd.io/USER_NAMES
|
||||
https://systemd.io/CONVERTING_TO_HOMED
|
||||
https://systemd.io/USERDB_AND_DESKTOPS
|
||||
|
||||
* Documentation for the on-disk Journal file format has been updated
|
||||
and has now moved to:
|
||||
|
||||
https://systemd.io/JOURNAL_FILE_FORMAT
|
||||
|
||||
* All D-Bus services shipped in systemd now implement the generic
|
||||
LogControl1 D-Bus API which allows clients to change log level +
|
||||
target of the service during runtime.
|
||||
|
||||
|
||||
CHANGES WITH 245:
|
||||
|
||||
* A new tool "systemd-repart" has been added, that operates as an
|
||||
|
|
33
TODO
33
TODO
|
@ -20,20 +20,10 @@ Features:
|
|||
* add --copy-from and --copy-to command to systemd-dissect which copies stuff
|
||||
in and out of a disk image
|
||||
|
||||
* add systemd.random_seed= on the kernel cmdline, taking some hex or base64
|
||||
encoded data. During earliest boot, credit it to entropy. This is not useful
|
||||
for general purpose systems, but certainly for testing environments in VMs
|
||||
and such, as it allows us to boot up instantly with fully initialized entropy
|
||||
pool even if RNG pass-thru is not available.
|
||||
|
||||
* Support ProtectProc= or so, using: https://patchwork.kernel.org/cover/11310197/
|
||||
|
||||
* if /usr/bin/swapoff fails due to OOM, log a friendly explanatory message about it
|
||||
|
||||
* warn if User=nobody is used in a unit file. It's the overflow UID after all,
|
||||
and the service might thus get access to files it really should not get
|
||||
access to on NFS and userns environments.
|
||||
|
||||
* build short web pages out of each catalog entry, build them along with man
|
||||
pages, and include hyperlinks to them in the journal output
|
||||
|
||||
|
@ -44,7 +34,7 @@ Features:
|
|||
anything like that.
|
||||
|
||||
* journald: do journal file writing out-of-process, with one writer process per
|
||||
client UID, so tht synthetic hash table collisions can slow down a specific
|
||||
client UID, so that synthetic hash table collisions can slow down a specific
|
||||
user's journal stream down but not the others.
|
||||
|
||||
* add "throttling" to sd-event event sources: optionally, when we wake up too
|
||||
|
@ -173,6 +163,10 @@ Features:
|
|||
- teach it to copy in unified kernel images and maybe type #1 boot loader spec entries from host
|
||||
- make it operate on loopback files, dissecting enough to find ESP to operate on
|
||||
|
||||
* Maybe add a separate GPT partition type to the discoverable partition spec
|
||||
for "hibernate" partitions, that are exactly like swap partitions but only
|
||||
activated right before hibernation and thus never used for regular swapping.
|
||||
|
||||
* by default, in systemd --user service bump the OOMAdjust to 100, as privs
|
||||
allow so that systemd survives
|
||||
|
||||
|
@ -234,6 +228,23 @@ Features:
|
|||
|
||||
* systemd-repart: allow managing the gpt read-only partition flag + auto-mount flag
|
||||
|
||||
* systemd-repart: allow boolean option that ensures that if existing partition
|
||||
doesn't exist within the configured size bounds the whole command fails. This
|
||||
is useful to implement ESP vs. XBOOTLDR schemes in installers: have one set
|
||||
of repart files for the case where ESP is large enough and one where it isn't
|
||||
and XBOOTLDR is added in instead. Then apply the former first, and if it
|
||||
fails to apply use the latter.
|
||||
|
||||
* systemd-repart: add per-partition option to never reuse existing partition
|
||||
and always create anew even if matching partition already exists.
|
||||
|
||||
* systemd-repart: add per-partition option to fail if partition already exist,
|
||||
i.e. is not added new. Similar, add option to fail if partition does not exist yet.
|
||||
|
||||
* systemd-repart: add --size=auto for generating/resizing images of minimal
|
||||
size, i.e. where the image file is sized exactly as large as necessary taking
|
||||
SizeMin= into account, but not a single byte larger.
|
||||
|
||||
* systemd-repart: allow disabling growing of specific partitions, or making
|
||||
them (think ESP: we don't ever want to grow it, since we cannot resize vfat)
|
||||
|
||||
|
|
|
@ -464,3 +464,23 @@ system shutdown.
|
|||
It is generally recommended to avoid such overly long mount point paths, or —
|
||||
if used anyway – manage them independently of systemd, i.e. establish them as
|
||||
well as tear them down automatically at system shutdown by other software.
|
||||
|
||||
-- b480325f9c394a7b802c231e51a2752c
|
||||
Subject: Special user @OFFENDING_USER@ configured, this is not safe!
|
||||
Defined-By: systemd
|
||||
Support: %SUPPORT_URL%
|
||||
Documentation: https://systemd.io/UIDS-GIDS
|
||||
|
||||
The unit @UNIT@ is configured to use User=@OFFENDING_USER@.
|
||||
|
||||
This is not safe. The @OFFENDING_USER@ user's main purpose on Linux-based
|
||||
operating systems is to be the owner of files that otherwise cannot be mapped
|
||||
to any local user. It's used by the NFS client and Linux user namespacing,
|
||||
among others. By running a unit's processes under the identity of this user
|
||||
they might possibly get read and even write access to such files that cannot
|
||||
otherwise be mapped.
|
||||
|
||||
It is strongly recommended to avoid running services under this user identity,
|
||||
in particular on systems using NFS or running containers. Allocate a user ID
|
||||
specific to this service, either statically via systemd-sysusers or dynamically
|
||||
via the DynamicUser= service setting.
|
||||
|
|
|
@ -64,7 +64,7 @@ desktop environments should adhere to the following conventions:
|
|||
is encouraged.
|
||||
* The RANDOM should be a string of random characters to ensure that multiple instances
|
||||
of the application can be launched.
|
||||
It can be ommitted in the case of a non-transient application services which can ensure
|
||||
It can be omitted in the case of a non-transient application services which can ensure
|
||||
multiple instances are not spawned, such as a DBus activated application.
|
||||
* If no application ID is available, the launcher should generate a reasonable
|
||||
name when possible (e.g. using `basename(argv[0])`). This name must not
|
||||
|
|
|
@ -257,7 +257,16 @@ boot, in order to ensure the entropy pool is filled up quickly.
|
|||
file. If done, `systemd-boot` will use the random seed file even if no
|
||||
system token is found in EFI variables.
|
||||
|
||||
With the three mechanisms described above it should be possible to provide
|
||||
4. A kernel command line option `systemd.random_seed=` may be used to pass in a
|
||||
base64 encoded seed to initialize the kernel's entropy pool from during
|
||||
early service manager initialization. This option is only safe in testing
|
||||
environments, as the random seed passed this way is accessible to
|
||||
unprivileged programs via `/proc/cmdline`. Using this option outside of
|
||||
testing environments is a security problem since cryptographic key material
|
||||
derived from the entropy pool initialized with a seed accessible to
|
||||
unprivileged programs should not be considered secret.
|
||||
|
||||
With the four mechanisms described above it should be possible to provide
|
||||
early-boot entropy in most cases. Specifically:
|
||||
|
||||
1. On EFI systems, `systemd-boot`'s random seed logic should make sure good
|
||||
|
@ -267,7 +276,8 @@ early-boot entropy in most cases. Specifically:
|
|||
2. On virtualized systems, the early `virtio-rng` hookup should ensure entropy
|
||||
is available early on — as long as the VM environment provides virtualized
|
||||
RNG devices, which they really should all do in 2019. Complain to your
|
||||
hosting provider if they don't.
|
||||
hosting provider if they don't. For VMs used in testing environments,
|
||||
`systemd.random_seed=` may be used as an alternative to a virtualized RNG.
|
||||
|
||||
3. On Intel/AMD systems systemd's own reliance on the kernel entropy pool is
|
||||
minimal (as RDRAND is used on those for UUID generation). This only works if
|
||||
|
@ -286,8 +296,9 @@ This primarily leaves two kind of systems in the cold:
|
|||
boot. Alternatively, consider implementing a solution similar to
|
||||
systemd-boot's random seed concept in your platform's boot loader.
|
||||
|
||||
2. Virtualized environments that lack both virtio-rng and RDRAND. Tough
|
||||
luck. Talk to your hosting provider, and ask them to fix this.
|
||||
2. Virtualized environments that lack both virtio-rng and RDRAND, outside of
|
||||
test environments. Tough luck. Talk to your hosting provider, and ask them
|
||||
to fix this.
|
||||
|
||||
3. Also note: if you deploy an image without any random seed and/or without
|
||||
installing any 'system token' in an EFI variable, as described above, this
|
||||
|
@ -410,6 +421,10 @@ This primarily leaves two kind of systems in the cold:
|
|||
information to possibly gain too much information about the current state
|
||||
of the kernel's entropy pool.
|
||||
|
||||
That said, we actually do implement this with the `systemd.random_seed=`
|
||||
kernel command line option. Don't use this outside of testing environments,
|
||||
however, for the aforementioned reasons.
|
||||
|
||||
12. *Why doesn't `systemd-boot` rewrite the 'system token' too each time
|
||||
when updating the random seed file stored in the ESP?*
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ if [ -z "$1" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# make sure the rules have been regenrated (in case man/update-man-rules was just run)
|
||||
# make sure the rules have been regenerated (in case man/update-man-rules was just run)
|
||||
ninja -C "@BUILD_ROOT@" version.h
|
||||
|
||||
target="man/$1.html"
|
||||
|
|
|
@ -468,8 +468,32 @@
|
|||
<term><varname>systemd.clock-usec=</varname></term>
|
||||
|
||||
<listitem><para>Takes a decimal, numeric timestamp in µs since January 1st 1970, 00:00am, to set the
|
||||
system clock to. The system time is set to the specified timestamp early during
|
||||
boot. It is not propagated to the hardware clock (RTC).</para></listitem>
|
||||
system clock to. The system time is set to the specified timestamp early during boot. It is not
|
||||
propagated to the hardware clock (RTC).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>systemd.random-seed=</varname></term>
|
||||
|
||||
<listitem><para>Takes a base64 encoded random seed value to credit with full entropy to the kernel's
|
||||
random pool during early service manager initialization. This option is useful in testing
|
||||
environments where delays due to random pool initialization in entropy starved virtual machines shall
|
||||
be avoided.</para>
|
||||
|
||||
<para>Note that if this option is used the seed is accessible to unprivileged programs from
|
||||
<filename>/proc/cmdline</filename>. This option is hence a security risk when used outside of test
|
||||
systems, since the (possibly) only seed used for initialization of the kernel's entropy pool might be
|
||||
easily acquired by unprivileged programs.</para>
|
||||
|
||||
<para>It is recommended to pass 512 bytes of randomized data (as that matches the Linux kernel pool
|
||||
size), which may be generated with a command like the following:</para>
|
||||
|
||||
<programlisting>dd if=/dev/urandom bs=512 count=1 status=none | base64 -w 0</programlisting>
|
||||
|
||||
<para>Again: do not use this option outside of testing environments, it's a security risk elsewhere,
|
||||
as secret key material derived from the entropy pool can possibly be reconstructed by unprivileged
|
||||
programs.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
|
|
@ -6,7 +6,7 @@ if [ -z "$1" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# make sure the rules have been regenrated (in case man/update-man-rules was just run)
|
||||
# make sure the rules have been regenerated (in case man/update-man-rules was just run)
|
||||
ninja -C "@BUILD_ROOT@" version.h
|
||||
|
||||
page="$(echo "$1" | sed 's/\./\\./')"
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
|
||||
<para>The domains prefixed with <literal>~</literal> are called "routing domains". All domains listed
|
||||
here (both search domains and routing domains after removing the <literal>~</literal> prefix) define
|
||||
a search path that preferably directs DNS queries to this inteface. This search path has an effect
|
||||
a search path that preferably directs DNS queries to this interface. This search path has an effect
|
||||
only when suitable per-link DNS servers are known. Such servers may be defined through the
|
||||
<varname>DNS=</varname> setting (see above) and dynamically at run time, for example from DHCP
|
||||
leases. If no per-link DNS servers are known, routing domains have no effect.</para>
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
<term><option>--timeout-signal=</option></term>
|
||||
<listitem>
|
||||
<para>Set the signal which <filename>systemd-udevd</filename> will send to
|
||||
forked off processes after reaching event timeout. The setting can be overriden
|
||||
forked off processes after reaching event timeout. The setting can be overridden
|
||||
at boot time with the kernel command line option
|
||||
<varname>udev.timeout_signal=</varname>. Setting to <constant>SIGABRT</constant>
|
||||
may be helpful in order to debug worker timeouts. Defaults to
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
#include <elf.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/random.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#if HAVE_SYS_AUXV_H
|
||||
|
@ -438,3 +440,36 @@ size_t random_pool_size(void) {
|
|||
/* Use the minimum as default, if we can't retrieve the correct value */
|
||||
return RANDOM_POOL_SIZE_MIN;
|
||||
}
|
||||
|
||||
int random_write_entropy(int fd, const void *seed, size_t size, bool credit) {
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(seed && size > 0);
|
||||
|
||||
if (credit) {
|
||||
_cleanup_free_ struct rand_pool_info *info = NULL;
|
||||
|
||||
/* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any
|
||||
* chance for confusion here. */
|
||||
if (size > INT_MAX / 8)
|
||||
return -EOVERFLOW;
|
||||
|
||||
info = malloc(offsetof(struct rand_pool_info, buf) + size);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
info->entropy_count = size * 8;
|
||||
info->buf_size = size;
|
||||
memcpy(info->buf, seed, size);
|
||||
|
||||
if (ioctl(fd, RNDADDENTROPY, info) < 0)
|
||||
return -errno;
|
||||
} else {
|
||||
r = loop_write(fd, seed, size, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,3 +38,5 @@ int rdrand(unsigned long *ret);
|
|||
#define RANDOM_POOL_SIZE_MAX (10U*1024U*1024U)
|
||||
|
||||
size_t random_pool_size(void);
|
||||
|
||||
int random_write_entropy(int fd, const void *seed, size_t size, bool credit);
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/random.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
|
@ -11,6 +9,7 @@
|
|||
#include "efivars.h"
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "random-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
/* If a random seed was passed by the boot loader in the LoaderRandomSeed EFI variable, let's credit it to
|
||||
|
@ -43,7 +42,6 @@ static void lock_down_efi_variables(void) {
|
|||
}
|
||||
|
||||
int efi_take_random_seed(void) {
|
||||
_cleanup_free_ struct rand_pool_info *info = NULL;
|
||||
_cleanup_free_ void *value = NULL;
|
||||
_cleanup_close_ int random_fd = -1;
|
||||
size_t size;
|
||||
|
@ -79,11 +77,6 @@ int efi_take_random_seed(void) {
|
|||
if (size == 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Random seed passed from boot loader has zero size? Ignoring.");
|
||||
|
||||
/* The kernel API only accepts "int" as entropy count (which is in bits), let's avoid any chance for
|
||||
* confusion here. */
|
||||
if (size > INT_MAX / 8)
|
||||
size = INT_MAX / 8;
|
||||
|
||||
random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (random_fd < 0)
|
||||
return log_warning_errno(errno, "Failed to open /dev/urandom for writing, ignoring: %m");
|
||||
|
@ -94,15 +87,8 @@ int efi_take_random_seed(void) {
|
|||
if (r < 0)
|
||||
return log_warning_errno(r, "Unable to mark EFI random seed as used, not using it: %m");
|
||||
|
||||
info = malloc(offsetof(struct rand_pool_info, buf) + size);
|
||||
if (!info)
|
||||
return log_oom();
|
||||
|
||||
info->entropy_count = size * 8;
|
||||
info->buf_size = size;
|
||||
memcpy(info->buf, value, size);
|
||||
|
||||
if (ioctl(random_fd, RNDADDENTROPY, info) < 0)
|
||||
r = random_write_entropy(random_fd, value, size, true);
|
||||
if (r < 0)
|
||||
return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m");
|
||||
|
||||
log_info("Successfully credited entropy passed from boot loader.");
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <sched.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "all-units.h"
|
||||
|
@ -2287,6 +2289,15 @@ int config_parse_user_group_compat(
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
if (strstr(lvalue, "User") && streq(k, NOBODY_USER_NAME))
|
||||
log_struct(LOG_NOTICE,
|
||||
"MESSAGE=%s:%u: Special user %s configured, this is not safe!", filename, line, k,
|
||||
"UNIT=%s", unit,
|
||||
"MESSAGE_ID=" SD_MESSAGE_NOBODY_USER_UNSUITABLE_STR,
|
||||
"OFFENDING_USER=%s", k,
|
||||
"CONFIG_FILE=%s", filename,
|
||||
"CONFIG_LINE=%u", line);
|
||||
|
||||
return free_and_replace(*user, k);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "ima-setup.h"
|
||||
#include "killall.h"
|
||||
|
@ -60,6 +61,7 @@
|
|||
#include "pretty-print.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "raw-clone.h"
|
||||
#include "rlimit-util.h"
|
||||
#if HAVE_SECCOMP
|
||||
|
@ -100,8 +102,8 @@ static enum {
|
|||
|
||||
static const char *arg_bus_introspect = NULL;
|
||||
|
||||
/* Those variables are initialized to 0 automatically, so we avoid uninitialized memory access.
|
||||
* Real defaults are assigned in reset_arguments() below. */
|
||||
/* Those variables are initialized to 0 automatically, so we avoid uninitialized memory access. Real
|
||||
* defaults are assigned in reset_arguments() below. */
|
||||
static char *arg_default_unit;
|
||||
static bool arg_system;
|
||||
static bool arg_dump_core;
|
||||
|
@ -149,6 +151,8 @@ static OOMPolicy arg_default_oom_policy;
|
|||
static CPUSet arg_cpu_affinity;
|
||||
static NUMAPolicy arg_numa_policy;
|
||||
static usec_t arg_clock_usec;
|
||||
static void *arg_random_seed;
|
||||
static size_t arg_random_seed_size;
|
||||
|
||||
/* A copy of the original environment block */
|
||||
static char **saved_env = NULL;
|
||||
|
@ -503,6 +507,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
|||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse systemd.clock_usec= argument, ignoring: %s", value);
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "systemd.random_seed")) {
|
||||
void *p;
|
||||
size_t sz;
|
||||
|
||||
if (proc_cmdline_value_missing(key, value))
|
||||
return 0;
|
||||
|
||||
r = unbase64mem(value, (size_t) -1, &p, &sz);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse systemd.random_seed= argument, ignoring: %s", value);
|
||||
|
||||
free(arg_random_seed);
|
||||
arg_random_seed = sz > 0 ? p : mfree(p);
|
||||
arg_random_seed_size = sz;
|
||||
|
||||
} else if (streq(key, "quiet") && !value) {
|
||||
|
||||
if (arg_show_status == _SHOW_STATUS_INVALID)
|
||||
|
@ -1574,6 +1593,9 @@ static void apply_clock_update(void) {
|
|||
if (arg_clock_usec == 0)
|
||||
return;
|
||||
|
||||
if (getpid_cached() != 1)
|
||||
return;
|
||||
|
||||
if (clock_settime(CLOCK_REALTIME, timespec_store(&ts, arg_clock_usec)) < 0)
|
||||
log_error_errno(errno, "Failed to set system clock to time specified on kernel command line: %m");
|
||||
else {
|
||||
|
@ -1584,6 +1606,40 @@ static void apply_clock_update(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void cmdline_take_random_seed(void) {
|
||||
_cleanup_close_ int random_fd = -1;
|
||||
size_t suggested;
|
||||
int r;
|
||||
|
||||
if (arg_random_seed_size == 0)
|
||||
return;
|
||||
|
||||
if (getpid_cached() != 1)
|
||||
return;
|
||||
|
||||
assert(arg_random_seed);
|
||||
suggested = random_pool_size();
|
||||
|
||||
if (arg_random_seed_size < suggested)
|
||||
log_warning("Random seed specified on kernel command line has size %zu, but %zu bytes required to fill entropy pool.",
|
||||
arg_random_seed_size, suggested);
|
||||
|
||||
random_fd = open("/dev/urandom", O_WRONLY|O_CLOEXEC|O_NOCTTY);
|
||||
if (random_fd < 0) {
|
||||
log_warning_errno(errno, "Failed to open /dev/urandom for writing, ignoring: %m");
|
||||
return;
|
||||
}
|
||||
|
||||
r = random_write_entropy(random_fd, arg_random_seed, arg_random_seed_size, true);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to credit entropy specified on kernel command line, ignoring: %m");
|
||||
return;
|
||||
}
|
||||
|
||||
log_notice("Successfully credited entropy passed on kernel command line.\n"
|
||||
"Note that the seed provided this way is accessible to unprivileged programs. This functionality should not be used outside of testing environments.");
|
||||
}
|
||||
|
||||
static void initialize_coredump(bool skip_setup) {
|
||||
#if ENABLE_COREDUMP
|
||||
if (getpid_cached() != 1)
|
||||
|
@ -2261,6 +2317,9 @@ static void reset_arguments(void) {
|
|||
|
||||
cpu_set_reset(&arg_cpu_affinity);
|
||||
numa_policy_reset(&arg_numa_policy);
|
||||
|
||||
arg_random_seed = mfree(arg_random_seed);
|
||||
arg_random_seed_size = 0;
|
||||
}
|
||||
|
||||
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
|
||||
|
@ -2580,8 +2639,7 @@ int main(int argc, char *argv[]) {
|
|||
/* For later on, see above... */
|
||||
log_set_target(LOG_TARGET_JOURNAL);
|
||||
|
||||
/* clear the kernel timestamp,
|
||||
* because we are in a container */
|
||||
/* clear the kernel timestamp, because we are in a container */
|
||||
kernel_timestamp = DUAL_TIMESTAMP_NULL;
|
||||
}
|
||||
|
||||
|
@ -2600,8 +2658,7 @@ int main(int argc, char *argv[]) {
|
|||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_open();
|
||||
|
||||
/* clear the kernel timestamp,
|
||||
* because we are not PID 1 */
|
||||
/* clear the kernel timestamp, because we are not PID 1 */
|
||||
kernel_timestamp = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
if (mac_selinux_init() < 0) {
|
||||
|
@ -2620,8 +2677,7 @@ int main(int argc, char *argv[]) {
|
|||
log_warning_errno(r, "Failed to redirect standard streams to /dev/null, ignoring: %m");
|
||||
}
|
||||
|
||||
/* Mount /proc, /sys and friends, so that /proc/cmdline and
|
||||
* /proc/$PID/fd is available. */
|
||||
/* Mount /proc, /sys and friends, so that /proc/cmdline and /proc/$PID/fd is available. */
|
||||
if (getpid_cached() == 1) {
|
||||
|
||||
/* Load the kernel modules early. */
|
||||
|
@ -2694,8 +2750,13 @@ int main(int argc, char *argv[]) {
|
|||
assert_se(chdir("/") == 0);
|
||||
|
||||
if (arg_action == ACTION_RUN) {
|
||||
/* Apply the systemd.clock_usec= kernel command line switch */
|
||||
apply_clock_update();
|
||||
if (!skip_setup) {
|
||||
/* Apply the systemd.clock_usec= kernel command line switch */
|
||||
apply_clock_update();
|
||||
|
||||
/* Apply random seed from kernel command line */
|
||||
cmdline_take_random_seed();
|
||||
}
|
||||
|
||||
/* A core pattern might have been specified via the cmdline. */
|
||||
initialize_core_pattern(skip_setup);
|
||||
|
|
|
@ -4524,24 +4524,27 @@ int unit_patch_contexts(Unit *u) {
|
|||
|
||||
if (ec->root_image &&
|
||||
(cc->device_policy != CGROUP_DEVICE_POLICY_AUTO || cc->device_allow)) {
|
||||
const char *p;
|
||||
|
||||
/* When RootImage= is specified, the following devices are touched. */
|
||||
r = cgroup_add_device_allow(cc, "/dev/loop-control", "rw");
|
||||
if (r < 0)
|
||||
return r;
|
||||
FOREACH_STRING(p, "/dev/loop-control", "/dev/mapper/control") {
|
||||
r = cgroup_add_device_allow(cc, p, "rw");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
FOREACH_STRING(p, "block-loop", "block-blkext", "block-device-mapper") {
|
||||
r = cgroup_add_device_allow(cc, p, "rwm");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = cgroup_add_device_allow(cc, "block-loop", "rwm");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = cgroup_add_device_allow(cc, "block-blkext", "rwm");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Make sure "block-loop" can be resolved, i.e. make sure "loop" shows up in /proc/devices */
|
||||
r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, "modprobe@loop.service", true, UNIT_DEPENDENCY_FILE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* Make sure "block-loop" can be resolved, i.e. make sure "loop" shows up in /proc/devices.
|
||||
* Same for mapper and verity. */
|
||||
FOREACH_STRING(p, "modprobe@loop.service", "modprobe@dm_mod.service", "modprobe@dm_verity.service") {
|
||||
r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, p, true, UNIT_DEPENDENCY_FILE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (ec->protect_clock) {
|
||||
|
|
|
@ -1380,7 +1380,7 @@ static int create_home(int argc, char *argv[], void *userdata) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Remember the original hashed paswords before we add our own, so that we can return to them later,
|
||||
/* Remember the original hashed passwords before we add our own, so that we can return to them later,
|
||||
* should the entered password turn out not to be acceptable. */
|
||||
original_hashed_passwords = strv_copy(hr->hashed_password);
|
||||
if (!original_hashed_passwords)
|
||||
|
|
|
@ -236,24 +236,10 @@ static int run(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
|
||||
if (IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED)) {
|
||||
_cleanup_free_ struct rand_pool_info *info = NULL;
|
||||
|
||||
info = malloc(offsetof(struct rand_pool_info, buf) + k);
|
||||
if (!info)
|
||||
return log_oom();
|
||||
|
||||
info->entropy_count = k * 8;
|
||||
info->buf_size = k;
|
||||
memcpy(info->buf, buf, k);
|
||||
|
||||
if (ioctl(random_fd, RNDADDENTROPY, info) < 0)
|
||||
return log_warning_errno(errno, "Failed to credit entropy, ignoring: %m");
|
||||
} else {
|
||||
r = loop_write(random_fd, buf, (size_t) k, false);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to write seed to /dev/urandom: %m");
|
||||
}
|
||||
r = random_write_entropy(random_fd, buf, k,
|
||||
IN_SET(lets_credit, CREDIT_ENTROPY_YES_PLEASE, CREDIT_ENTROPY_YES_FORCED));
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to write seed to /dev/urandom: %m");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,7 +291,7 @@ static int run(int argc, char *argv[]) {
|
|||
* entropy later on. Let's keep that in mind by setting an extended attribute. on the file */
|
||||
if (getrandom_worked)
|
||||
if (fsetxattr(seed_fd, "user.random-seed-creditable", "1", 1, 0) < 0)
|
||||
log_full_errno(IN_SET(errno, ENOSYS, EOPNOTSUPP) ? LOG_DEBUG : LOG_WARNING, errno,
|
||||
log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno,
|
||||
"Failed to mark seed file as creditable, ignoring: %m");
|
||||
}
|
||||
|
||||
|
|
|
@ -713,28 +713,6 @@ int efi_loader_get_features(uint64_t *ret) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool efi_loader_entry_name_valid(const char *s) {
|
||||
if (isempty(s))
|
||||
return false;
|
||||
|
||||
if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
|
||||
return false;
|
||||
|
||||
return in_charset(s, ALPHANUMERICAL "+-_.");
|
||||
}
|
||||
|
||||
char *efi_tilt_backslashes(char *s) {
|
||||
char *p;
|
||||
|
||||
for (p = s; *p; p++)
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
|
||||
_cleanup_free_ char *v = NULL, *fn = NULL;
|
||||
static struct stat cache_stat = {};
|
||||
|
@ -804,3 +782,25 @@ int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool efi_loader_entry_name_valid(const char *s) {
|
||||
if (isempty(s))
|
||||
return false;
|
||||
|
||||
if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
|
||||
return false;
|
||||
|
||||
return in_charset(s, ALPHANUMERICAL "+-_.");
|
||||
}
|
||||
|
||||
char *efi_tilt_backslashes(char *s) {
|
||||
char *p;
|
||||
|
||||
for (p = s; *p; p++)
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -166,6 +166,10 @@ _SD_BEGIN_DECLARATIONS;
|
|||
#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR \
|
||||
SD_ID128_MAKE_STR(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
|
||||
|
||||
#define SD_MESSAGE_NOBODY_USER_UNSUITABLE SD_ID128_MAKE(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c)
|
||||
#define SD_MESSAGE_NOBODY_USER_UNSUITABLE_STR \
|
||||
SD_ID128_MAKE_STR(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c)
|
||||
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -413,7 +413,7 @@ static int worker_mark_block_device_read_only(sd_device *dev) {
|
|||
|
||||
/* Exclude synthetic devices for now, this is supposed to be a safety feature to avoid modification
|
||||
* of physical devices, and what sits on top of those doesn't really matter if we don't allow the
|
||||
* underlying block devices to recieve changes. */
|
||||
* underlying block devices to receive changes. */
|
||||
if (STARTSWITH_SET(val, "dm-", "md", "drbd", "loop", "nbd", "zram"))
|
||||
return 0;
|
||||
|
||||
|
|
Loading…
Reference in New Issue