mirror of
https://github.com/systemd/systemd
synced 2025-10-01 17:54:45 +02:00
Compare commits
34 Commits
c83e44110c
...
10f4d47037
Author | SHA1 | Date | |
---|---|---|---|
![]() |
10f4d47037 | ||
![]() |
60d3137024 | ||
![]() |
048e043375 | ||
![]() |
67e700bad7 | ||
![]() |
8ebfd50aaf | ||
![]() |
6c3f7ca036 | ||
![]() |
267294e08d | ||
![]() |
d6191ed529 | ||
![]() |
897a25617d | ||
![]() |
a5e5e102ba | ||
![]() |
5bd7ebb332 | ||
![]() |
d1f8fbea9f | ||
![]() |
990e7e87ad | ||
![]() |
c6ebf89b8f | ||
![]() |
2f4d8e577c | ||
![]() |
dda7d0a4d6 | ||
![]() |
f2ec239c2b | ||
![]() |
1f9441a72b | ||
![]() |
85c8eac822 | ||
![]() |
1a7c5ec4b2 | ||
![]() |
8770c8135b | ||
![]() |
e7637751c4 | ||
![]() |
05c6f341b1 | ||
![]() |
209c14705d | ||
![]() |
6ef06723b1 | ||
![]() |
fd03a6a92b | ||
![]() |
addddf565b | ||
![]() |
aa96ef86a7 | ||
![]() |
d55ed7de34 | ||
![]() |
fa256f43e7 | ||
![]() |
bb4e030fcb | ||
![]() |
4ad017cda5 | ||
![]() |
f70e6fb471 | ||
![]() |
8b8024f1c2 |
65
NEWS
65
NEWS
@ -167,6 +167,10 @@ CHANGES WITH 248:
|
||||
i.e. whether the interface is always upped, always downed, or may be
|
||||
upped/downed by the user using "ip dev".
|
||||
|
||||
* The default for the Broadcast= setting in .network files has slightly
|
||||
changed: the broadcast address will not be configured for wireguard
|
||||
devices.
|
||||
|
||||
* systemd.netdev files gained a [VLAN] Protocol=, IngressQOSMaps=,
|
||||
EgressQOSMaps=, and [MACVLAN] BroadcastMulticastQueueLength=
|
||||
configuration options for VLAN packet handling.
|
||||
@ -229,17 +233,23 @@ CHANGES WITH 248:
|
||||
|
||||
* systemd-nspawn gained the ability to configure the firewall using the
|
||||
nftables subsystem (in addition to the existing iptables
|
||||
support). Similar, systemd-networkd's IPMasquerade= option now
|
||||
support). Similarly, systemd-networkd's IPMasquerade= option now
|
||||
supports nftables as back-end, too. In both cases NAT on IPv6 is now
|
||||
supported too, in addition to IPv4 (the iptables back-end still is
|
||||
IPv4-only).
|
||||
|
||||
"IPMasquerade=yes", which was the same as "IPMasquerade=ipv4" before,
|
||||
retains its meaning, but has been deprecated. Please switch to either
|
||||
"ivp4" or "both" (if covering IPv6 is desired).
|
||||
|
||||
* systemd-importd will now download .verity and .roothash.p7s files
|
||||
along with the machine image (as exposed via machinectl pull-raw).
|
||||
|
||||
* systemd-oomd now gained a new DefaultMemoryPressureDurationSec=
|
||||
setting to configure the time a unit's cgroup needs to exceed memory
|
||||
pressure limits before action will be taken.
|
||||
pressure limits before action will be taken, and a new
|
||||
ManagedOOMPreference=none|avoid|omit setting to avoid killing certain
|
||||
units.
|
||||
|
||||
systemd-oomd is now considered fully supported (the usual
|
||||
backwards-compatiblity promises apply). Swap is not required for
|
||||
@ -256,8 +266,8 @@ CHANGES WITH 248:
|
||||
ignored. The goal is to honour configuration as specified by the
|
||||
user.
|
||||
|
||||
* systemd-hostnamed now exports the fallback hostname and the source of
|
||||
the configured hostname ("static", "transient", or "fallback") as
|
||||
* systemd-hostnamed now exports the default hostname and the source of
|
||||
the configured hostname ("static", "transient", or "default") as
|
||||
D-Bus properties.
|
||||
|
||||
* systemd-hostnamed now exports the "HardwareVendor" and
|
||||
@ -321,6 +331,10 @@ CHANGES WITH 248:
|
||||
warning is emitted during build. Support is slated to be removed in
|
||||
about a year (when the Debian Bookworm release development starts).
|
||||
|
||||
* Systems with the legacy cgroup v1 hierarchy are now marked as
|
||||
"tainted", to make it clearer that using the legacy hierarchy is not
|
||||
recommended.
|
||||
|
||||
* The main git development branch has been renamed to 'main'.
|
||||
|
||||
* mmcblk[0-9]boot[0-9] devices will no longer be probed automatically
|
||||
@ -332,11 +346,12 @@ CHANGES WITH 248:
|
||||
by programs for detecting whether they were forked off by the service
|
||||
manager itself or are a process forked off further down the tree.
|
||||
|
||||
* The sd-device API gained three new calls sd_device_get_action() (for
|
||||
determining the uevent add/remove/change/… action the device object
|
||||
has been seen for), sd_device_get_seqno() (for determining the uevent
|
||||
sequence number) and sd_device_new_from_stat_rdev() (for allocating a
|
||||
new sd_device object from stat() data of a device node).
|
||||
* The sd-device API gained four new calls: sd_device_get_action() to
|
||||
determine the uevent add/remove/change/… action the device object has
|
||||
been seen for, sd_device_get_seqno() to determine the uevent sequence
|
||||
number, sd_device_new_from_stat_rdev() to allocate a new sd_device
|
||||
object from stat(2) data of a device node, and sd_device_trigger() to
|
||||
write to the 'uevent' attribute of a device.
|
||||
|
||||
* For most tools the --no-legend= switch has been replaced by
|
||||
--legend=no and --legend=yes, to force whether tables are shown with
|
||||
@ -371,6 +386,38 @@ CHANGES WITH 248:
|
||||
* portablectl gained a new "reattach" verb for detaching/reattaching a
|
||||
portable service image, useful for updating images on-the-fly.
|
||||
|
||||
Contributions from: Adam Nielsen, Adrian Vovk, AJ Jordan, Alan Perry,
|
||||
Alexander Batischev, Ali Abdallah, Andrew Balmos, Anita Zhang, Ansgar
|
||||
Burchardt, Antonius Frie, Ardy, Arian van Putten, Ariel Fermani, Arnaud
|
||||
T, A S Alam, Bastien Nocera, Benjamin Berg, Benjamin Robin, Björn
|
||||
Daase, chri2, Christian Ehrhardt, Christian Hesse, Christopher Obbard,
|
||||
clayton craft, corvusnix, cprn, d032747, Daan De Meyer, Daniele Medri,
|
||||
Dan Streetman, Darren Ng, David Edmundson, Deepak Rawat, Devon Pringle,
|
||||
Dmitry Borodaenko, dropsignal, Einsler Lee, Endre Szabo, Evgeny
|
||||
Vereshchagin, Fabian Affolter, Felipe Borges, feliperodriguesfr, Felix
|
||||
Stupp, Florian Hülsmann, Florian Klink, Florian Westphal, Franck Bui,
|
||||
Frantisek Sumsal, Gablegritule, Gaël PORTAY, Gaurav, Giedrius
|
||||
Statkevičius, Greg Depoire--Ferrer, Hans de Goede, heretoenhance, Iago
|
||||
López Galeiras, igo95862, Ilya Dmitrichenko, Jameer Pathan, Jan Tojnar,
|
||||
Jiehong, Jinyuan Si, John Slade, Jonathan G. Underwood, Jonathan
|
||||
McDowell, Josh Triplett, Joshua Watt, Julia Cartwright, Julien Humbert,
|
||||
Kairui Song, Karel Zak, Kevin P. Fleming, Khem Raj, Konomi, krissgjeng,
|
||||
l4gfcm, Lennart Poettering, Luca Boccassi, Luca BRUNO, Lucas
|
||||
Werkmeister, Luka Kudra, Luna Jernberg, Marc-André Lureau, Matthias
|
||||
Klumpp, Matt Turner, Michael Marley, Michal Fabik, Michał Kopeć, Michal
|
||||
Sekletár, Mike Gilbert, milovlad, moson-mo, Nick, nihilix-melix, Oğuz
|
||||
Ersen, Ondrej Mosnacek, pali, Pavel Hrdina, Pavel Sapezhko, Peter
|
||||
Hutterer, Pierre Dubouilh, Piotr Drąg, Richard Laager, rnhmjoj,
|
||||
RussianNeuroMancer, Sebastiaan van Stijn, Sergey Bugaev, shenyangyang4,
|
||||
Simonas Kazlauskas, Stefan Agner, Steve Ramage, Susant Sahani, Sven
|
||||
Mueller, Tad Fisher, Takashi Iwai, Thomas Haller, Topi Miettinen,
|
||||
Torsten Hilbrich, Tyler Hicks, Ulrich Ölmann, Vinnie Magro, Vito
|
||||
Caputo, Vlad, walbit-de, Weblate, Weblate (bot), Whired Planck, wouter
|
||||
bolsterlee, Yuri Chornoivan, Yu Watanabe, Zach Smith, Zbigniew
|
||||
Jędrzejewski-Szmek, Zmicer Turok, Дамјан Георгиевски
|
||||
|
||||
— Warsaw, 2021-02-23
|
||||
|
||||
CHANGES WITH 247:
|
||||
|
||||
* KERNEL API INCOMPATIBILITY: Linux 4.14 introduced two new uevents
|
||||
|
@ -56,6 +56,10 @@ All tools:
|
||||
* `$SYSTEMD_EFI_OPTIONS` — if set, used instead of the string in the
|
||||
`SystemdOptions` EFI variable. Analogous to `$SYSTEMD_PROC_CMDLINE`.
|
||||
|
||||
* `$SYSTEMD_DEFAULT_HOSTNAME` — override the compiled-in fallback hostname
|
||||
(relevant in particular for the system manager and `systemd-hostnamed`).
|
||||
Must be a valid hostname (either a single label or a FQDN).
|
||||
|
||||
* `$SYSTEMD_IN_INITRD=[auto|lenient|0|1]` — if set, specifies initrd detection
|
||||
method. Defaults to `auto`. Behavior is defined as follows:
|
||||
`auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted
|
||||
|
@ -116,6 +116,11 @@ footer {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
/* Make tables vertically aligned to the top */
|
||||
tbody td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* Github Code Highlighting */
|
||||
.highlight table td { padding: 5px; }
|
||||
.highlight table pre { margin: 0; }
|
||||
|
@ -63,7 +63,7 @@ node /org/freedesktop/hostname1 {
|
||||
readonly s StaticHostname = '...';
|
||||
readonly s PrettyHostname = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s FallbackHostname = '...';
|
||||
readonly s DefaultHostname = '...';
|
||||
readonly s HostnameSource = '...';
|
||||
readonly s IconName = '...';
|
||||
readonly s Chassis = '...';
|
||||
@ -124,7 +124,7 @@ node /org/freedesktop/hostname1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="PrettyHostname"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="FallbackHostname"/>
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultHostname"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="HostnameSource"/>
|
||||
|
||||
@ -183,13 +183,15 @@ node /org/freedesktop/hostname1 {
|
||||
set this setting will be the empty string. Applications should then find a suitable fallback, such as the
|
||||
dynamic hostname.</para>
|
||||
|
||||
<para>The <varname>FallbackHostname</varname> property exposes the fallback hostname (configured at
|
||||
compilation time).</para>
|
||||
<para>The <varname>DefaultHostname</varname> property exposes the default hostname (configured through
|
||||
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>, or a
|
||||
fallback set at compilation time).</para>
|
||||
|
||||
<para>The <varname>HostnameSource</varname> property exposes the origin of the currently configured
|
||||
hostname. One of <literal>static</literal> (set from <filename>/etc/hostname</filename>),
|
||||
<literal>transient</literal> (a non-permanent hostname from an external source),
|
||||
<literal>fallback</literal> (the compiled-in fallback value).</para>
|
||||
<literal>default</literal> (the value from <filename>os-release</filename> or the the compiled-in
|
||||
fallback).</para>
|
||||
|
||||
<para>The <varname>IconName</varname> property exposes the <emphasis>icon name</emphasis> following the
|
||||
XDG icon naming spec. If not set, information such as the chassis type (see below) is used to find a
|
||||
@ -332,8 +334,8 @@ node /org/freedesktop/hostname1 {
|
||||
<listitem><para>Limit the hostname to 63 chars, which is the length of a DNS label.</para></listitem>
|
||||
|
||||
<listitem><para>If after stripping special chars the empty string is the result, you can pass this
|
||||
as-is to <filename>systemd-hostnamed</filename> in which case it will automatically use
|
||||
<literal>&FALLBACK_HOSTNAME;</literal>.</para></listitem>
|
||||
as-is to <filename>systemd-hostnamed</filename> in which case it will automatically use a suitable
|
||||
fallback.</para></listitem>
|
||||
|
||||
<listitem><para>Uppercase charaacters should be replaced with their lowercase equivalents.
|
||||
</para></listitem>
|
||||
|
@ -317,6 +317,23 @@
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DEFAULT_HOSTNAME=</varname></term>
|
||||
|
||||
<listitem><para>A string specifying the hostname if
|
||||
<citerefentry><refentrytitle>hostname</refentrytitle><manvolnum>5</manvolnum></citerefentry> is not
|
||||
present and no other configuration source specifies the hostname. Must be either a single DNS label
|
||||
(a string composed of 7-bit ASCII lower-case characters and no spaces or dots, limited to the format
|
||||
allowed for DNS domain name labels), or a sequence of such labels separated by single dots that forms
|
||||
a valid DNS FQDN. The total length must be at most 64 characters.</para>
|
||||
|
||||
<para>See
|
||||
<citerefentry><refentrytitle>org.freedesktop.hostname1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for a description of how
|
||||
<citerefentry><refentrytitle>systemd-hostnamed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
determines the fallback hostname.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SYSEXT_LEVEL=</varname></term>
|
||||
|
||||
|
@ -31,7 +31,9 @@
|
||||
<filename>/etc/systemd/system.conf.d/*.conf</filename>,
|
||||
<filename>/run/systemd/system.conf.d/*.conf</filename>,
|
||||
<filename>/usr/lib/systemd/system.conf.d/*.conf</filename></para>
|
||||
<para><filename>/etc/systemd/user.conf</filename>,
|
||||
|
||||
<para><filename>~/.config/systemd/user.conf</filename>,
|
||||
<filename>/etc/systemd/user.conf</filename>,
|
||||
<filename>/etc/systemd/user.conf.d/*.conf</filename>,
|
||||
<filename>/run/systemd/user.conf.d/*.conf</filename>,
|
||||
<filename>/usr/lib/systemd/user.conf.d/*.conf</filename></para>
|
||||
@ -40,16 +42,16 @@
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>When run as a system instance, systemd interprets the
|
||||
configuration file <filename>system.conf</filename> and the files
|
||||
in <filename>system.conf.d</filename> directories; when run as a
|
||||
user instance, systemd interprets the configuration file
|
||||
<filename>user.conf</filename> and the files in
|
||||
<filename>user.conf.d</filename> directories. These configuration
|
||||
files contain a few settings controlling basic manager
|
||||
operations. See
|
||||
<citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
for a general description of the syntax.</para>
|
||||
<para>When run as a system instance, <command>systemd</command> interprets the configuration file
|
||||
<filename>system.conf</filename> and the files in <filename>system.conf.d</filename> directories; when
|
||||
run as a user instance, it interprets the configuration file <filename>user.conf</filename> (either in
|
||||
the home directory of the user, or if not found, under <filename>/etc/systemd/</filename>) and the files
|
||||
in <filename>user.conf.d</filename> directories. These configuration files contain a few settings
|
||||
controlling basic manager operations.</para>
|
||||
|
||||
<para>See
|
||||
<citerefentry><refentrytitle>systemd.syntax</refentrytitle><manvolnum>7</manvolnum></citerefentry> for a
|
||||
general description of the syntax.</para>
|
||||
</refsect1>
|
||||
|
||||
<xi:include href="standard-conf.xml" xpointer="main-conf" />
|
||||
@ -321,11 +323,10 @@
|
||||
<varlistentry>
|
||||
<term><varname>DefaultEnvironment=</varname></term>
|
||||
|
||||
<listitem><para>Sets manager environment variables passed to
|
||||
all executed processes. Takes a space-separated list of
|
||||
variable assignments. See
|
||||
<citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
for details about environment variables.</para>
|
||||
<listitem><para>Configures environment variables passed to all executed processes. Takes a
|
||||
space-separated list of variable assignments. See <citerefentry
|
||||
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
details about environment variables.</para>
|
||||
|
||||
<para>Example:
|
||||
|
||||
@ -337,6 +338,20 @@
|
||||
<literal>VAR3</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ManagerEnvironment=</varname></term>
|
||||
|
||||
<listitem><para>Takes the same arguments as <varname>DefaultEnvironment=</varname>, see above. Sets
|
||||
environment variables just for the manager process itself. These variables are not inherited by
|
||||
processes spawned by the service manager, use <varname>DefaultEnvironment=</varname> for that. Note
|
||||
that these variables are merged into the existing environment block. In particular, in case of the
|
||||
system manager, this includes variables set by the kernel based on the kernel command line.</para>
|
||||
|
||||
<para>Setting environment variables for the manager process may be useful to modify its behaviour.
|
||||
See <ulink url="https://systemd.io/ENVIRONMENT">ENVIRONMENT</ulink> for a descriptions of some
|
||||
variables understood by <command>systemd</command>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DefaultCPUAccounting=</varname></term>
|
||||
<term><varname>DefaultBlockIOAccounting=</varname></term>
|
||||
|
@ -60,7 +60,7 @@
|
||||
<filename>$XDG_RUNTIME_DIR/systemd/user.control/*</filename>
|
||||
<filename>$XDG_RUNTIME_DIR/systemd/transient/*</filename>
|
||||
<filename>$XDG_RUNTIME_DIR/systemd/generator.early/*</filename>
|
||||
<filename>$XDG_CONFIG_HOME/systemd/user/*</filename>
|
||||
<filename>~/.config/systemd/user/*</filename>
|
||||
<filename>$XDG_CONFIG_DIRS/systemd/user/*</filename>
|
||||
<filename>/etc/systemd/user/*</filename>
|
||||
<filename>$XDG_RUNTIME_DIR/systemd/user/*</filename>
|
||||
@ -1456,14 +1456,25 @@
|
||||
<varlistentry>
|
||||
<term><varname>ConditionControlGroupController=</varname></term>
|
||||
|
||||
<listitem><para>Verify that the given cgroup controller (eg. <literal>cpu</literal>) is available
|
||||
for use on the system. For example, a particular controller may not be available if it was disabled
|
||||
on the kernel command line with <varname>cgroup_disable=controller</varname>. Multiple controllers
|
||||
may be passed with a space separating them; in this case the condition will only pass if all listed
|
||||
controllers are available for use. Controllers unknown to systemd are ignored. Valid controllers
|
||||
are <literal>cpu</literal>, <literal>cpuacct</literal>, <literal>io</literal>,
|
||||
<literal>blkio</literal>, <literal>memory</literal>, <literal>devices</literal>, and
|
||||
<literal>pids</literal>.</para>
|
||||
<listitem><para>Check whether given cgroup controllers (eg. <literal>cpu</literal>) are available
|
||||
for use on the system or whether the legacy v1 cgroup or the modern v2 cgroup hierarchy is used.
|
||||
</para>
|
||||
|
||||
<para>Multiple controllers may be passed with a space separating them; in this case the condition
|
||||
will only pass if all listed controllers are available for use. Controllers unknown to systemd are
|
||||
ignored. Valid controllers are <literal>cpu</literal>, <literal>cpuacct</literal>,
|
||||
<literal>io</literal>, <literal>blkio</literal>, <literal>memory</literal>,
|
||||
<literal>devices</literal>, and <literal>pids</literal>. Even if available in the kernel, a
|
||||
particular controller may not be available if it was disabled on the kernel command line with
|
||||
<varname>cgroup_disable=controller</varname>.</para>
|
||||
|
||||
<para>Alternatively, two special strings <literal>v1</literal> and <literal>v2</literal> may be
|
||||
specified (without any controller names). <literal>v2</literal> will pass if the unified v2 cgroup
|
||||
hierachy is used, and <literal>v1</literal> will pass if the legacy v1 hierarchy or the hybrid
|
||||
hierarchy are used (see the discussion of <varname>systemd.unified_cgroup_hierarchy</varname> and
|
||||
<varname>systemd.legacy_systemd_cgroup_controller</varname> in
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for more information).</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
project('systemd', 'c',
|
||||
version : '247',
|
||||
version : '248',
|
||||
license : 'LGPLv2+',
|
||||
default_options: [
|
||||
'c_std=gnu99',
|
||||
@ -13,7 +13,7 @@ project('systemd', 'c',
|
||||
meson_version : '>= 0.46',
|
||||
)
|
||||
|
||||
libsystemd_version = '0.30.0'
|
||||
libsystemd_version = '0.31.0'
|
||||
libudev_version = '1.7.0'
|
||||
|
||||
# We need the same data in two different formats, ugh!
|
||||
|
15
po/sk.po
15
po/sk.po
@ -2,21 +2,22 @@
|
||||
#
|
||||
# Slovak translation for systemd.
|
||||
# Dušan Kazik <prescott66@gmail.com>, 2017.
|
||||
#
|
||||
# Frantisek Sumsal <frantisek@sumsal.cz>, 2021.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: systemd master\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-01-08 17:48+0100\n"
|
||||
"PO-Revision-Date: 2017-06-25 11:03+0200\n"
|
||||
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
|
||||
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
|
||||
"PO-Revision-Date: 2021-02-22 20:21+0000\n"
|
||||
"Last-Translator: Frantisek Sumsal <frantisek@sumsal.cz>\n"
|
||||
"Language-Team: Slovak <https://translate.fedoraproject.org/projects/systemd/"
|
||||
"master/sk/>\n"
|
||||
"Language: sk\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
|
||||
"X-Generator: Poedit 2.0.2\n"
|
||||
"X-Generator: Weblate 4.4.2\n"
|
||||
|
||||
#: src/core/org.freedesktop.systemd1.policy.in:22
|
||||
msgid "Send passphrase back to system"
|
||||
@ -235,11 +236,11 @@ msgstr ""
|
||||
|
||||
#: src/login/org.freedesktop.login1.policy:44
|
||||
msgid "Allow applications to inhibit system sleep"
|
||||
msgstr ""
|
||||
msgstr "Umožnenie aplikáciám odložiť spánok systému"
|
||||
|
||||
#: src/login/org.freedesktop.login1.policy:45
|
||||
msgid "Authentication is required for an application to inhibit system sleep."
|
||||
msgstr ""
|
||||
msgstr "Vyžaduje sa overenie totožnosti na odloženie spánku systému aplikáciou."
|
||||
|
||||
#: src/login/org.freedesktop.login1.policy:55
|
||||
msgid "Allow applications to delay system sleep"
|
||||
|
@ -768,6 +768,21 @@ int set_unset_env(const char *name, const char *value, bool overwrite) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int putenv_dup(const char *assignment, bool override) {
|
||||
const char *e, *n;
|
||||
|
||||
e = strchr(assignment, '=');
|
||||
if (!e)
|
||||
return -EINVAL;
|
||||
|
||||
n = strndupa(assignment, e - assignment);
|
||||
|
||||
/* This is like putenv(), but uses setenv() so that our memory doesn't become part of environ[]. */
|
||||
if (setenv(n, e + 1, override) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setenv_systemd_exec_pid(bool update_only) {
|
||||
char str[DECIMAL_STR_MAX(pid_t)];
|
||||
const char *e;
|
||||
|
@ -58,6 +58,9 @@ int getenv_bool_secure(const char *p);
|
||||
/* Like setenv, but calls unsetenv if value == NULL. */
|
||||
int set_unset_env(const char *name, const char *value, bool overwrite);
|
||||
|
||||
/* Like putenv, but duplicates the memory like setenv. */
|
||||
int putenv_dup(const char *assignment, bool override);
|
||||
|
||||
int setenv_systemd_exec_pid(bool update_only);
|
||||
|
||||
/* Parses and does sanity checks on an environment variable containing
|
||||
|
@ -3,14 +3,39 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "os-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
char* get_default_hostname(void) {
|
||||
int r;
|
||||
|
||||
const char *e = secure_getenv("SYSTEMD_DEFAULT_HOSTNAME");
|
||||
if (e) {
|
||||
if (hostname_is_valid(e, 0))
|
||||
return strdup(e);
|
||||
log_debug("Invalid hostname in $SYSTEMD_DEFAULT_HOSTNAME, ignoring: %s", e);
|
||||
}
|
||||
|
||||
_cleanup_free_ char *f = NULL;
|
||||
r = parse_os_release(NULL, "DEFAULT_HOSTNAME", &f);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to parse os-release, ignoring: %m");
|
||||
else if (f) {
|
||||
if (hostname_is_valid(f, 0))
|
||||
return TAKE_PTR(f);
|
||||
log_debug("Invalid hostname in os-release, ignoring: %s", f);
|
||||
}
|
||||
|
||||
return strdup(FALLBACK_HOSTNAME);
|
||||
}
|
||||
|
||||
char* gethostname_malloc(void) {
|
||||
struct utsname u;
|
||||
const char *s;
|
||||
@ -23,7 +48,7 @@ char* gethostname_malloc(void) {
|
||||
|
||||
s = u.nodename;
|
||||
if (isempty(s) || streq(s, "(none)"))
|
||||
s = FALLBACK_HOSTNAME;
|
||||
return get_default_hostname();
|
||||
|
||||
return strdup(s);
|
||||
}
|
||||
@ -31,6 +56,7 @@ char* gethostname_malloc(void) {
|
||||
char* gethostname_short_malloc(void) {
|
||||
struct utsname u;
|
||||
const char *s;
|
||||
_cleanup_free_ char *f = NULL;
|
||||
|
||||
/* Like above, but kills the FQDN part if present. */
|
||||
|
||||
@ -38,7 +64,10 @@ char* gethostname_short_malloc(void) {
|
||||
|
||||
s = u.nodename;
|
||||
if (isempty(s) || streq(s, "(none)") || s[0] == '.') {
|
||||
s = FALLBACK_HOSTNAME;
|
||||
s = f = get_default_hostname();
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
assert(s[0] != '.');
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "macro.h"
|
||||
#include "strv.h"
|
||||
|
||||
char* get_default_hostname(void);
|
||||
char* gethostname_malloc(void);
|
||||
char* gethostname_short_malloc(void);
|
||||
int gethostname_strict(char **ret);
|
||||
|
@ -376,6 +376,7 @@ static inline int __coverity_check_and_return__(int condition) {
|
||||
|
||||
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
|
||||
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
|
||||
#define STRV_MAKE_CONST(...) ((const char* const*) ((const char*[]) { __VA_ARGS__, NULL }))
|
||||
|
||||
/* Pointers range from NULL to POINTER_MAX */
|
||||
#define POINTER_MAX ((void*) UINTPTR_MAX)
|
||||
|
@ -170,6 +170,8 @@ basic_sources = files('''
|
||||
nulstr-util.h
|
||||
ordered-set.c
|
||||
ordered-set.h
|
||||
os-util.c
|
||||
os-util.h
|
||||
parse-util.c
|
||||
parse-util.h
|
||||
path-lookup.c
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "discover-image.h"
|
||||
#include "env-file.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
@ -9,8 +8,27 @@
|
||||
#include "fs-util.h"
|
||||
#include "macro.h"
|
||||
#include "os-util.h"
|
||||
#include "path-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
bool image_name_is_valid(const char *s) {
|
||||
if (!filename_is_valid(s))
|
||||
return false;
|
||||
|
||||
if (string_has_cc(s, NULL))
|
||||
return false;
|
||||
|
||||
if (!utf8_is_valid(s))
|
||||
return false;
|
||||
|
||||
/* Temporary files for atomically creating new files */
|
||||
if (startswith(s, ".#"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int path_is_extension_tree(const char *path, const char *extension) {
|
||||
int r;
|
||||
@ -118,7 +136,7 @@ static int parse_release_internal(const char *root, const char *extension, va_li
|
||||
return parse_env_filev(f, p, ap);
|
||||
}
|
||||
|
||||
int parse_extension_release(const char *root, const char *extension, ...) {
|
||||
int _parse_extension_release(const char *root, const char *extension, ...) {
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
@ -129,7 +147,7 @@ int parse_extension_release(const char *root, const char *extension, ...) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int parse_os_release(const char *root, ...) {
|
||||
int _parse_os_release(const char *root, ...) {
|
||||
va_list ap;
|
||||
int r;
|
||||
|
||||
@ -193,74 +211,3 @@ int load_extension_release_pairs(const char *root, const char *extension, char *
|
||||
|
||||
return load_env_file_pairs(f, p, ret);
|
||||
}
|
||||
|
||||
int extension_release_validate(
|
||||
const char *name,
|
||||
const char *host_os_release_id,
|
||||
const char *host_os_release_version_id,
|
||||
const char *host_os_release_sysext_level,
|
||||
char **extension_release) {
|
||||
|
||||
const char *extension_release_id = NULL, *extension_release_sysext_level = NULL;
|
||||
|
||||
assert(name);
|
||||
assert(!isempty(host_os_release_id));
|
||||
|
||||
/* Now that we can look into the extension image, let's see if the OS version is compatible */
|
||||
if (strv_isempty(extension_release)) {
|
||||
log_debug("Extension '%s' carries no extension-release data, ignoring extension.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extension_release_id = strv_env_pairs_get(extension_release, "ID");
|
||||
if (isempty(extension_release_id)) {
|
||||
log_debug("Extension '%s' does not contain ID in extension-release but requested to match '%s'",
|
||||
name, strna(host_os_release_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!streq_ptr(host_os_release_id, extension_release_id)) {
|
||||
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
|
||||
name, strna(extension_release_id), strna(host_os_release_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Rolling releases do not typically set VERSION_ID (eg: ArchLinux) */
|
||||
if (isempty(host_os_release_version_id) && isempty(host_os_release_sysext_level)) {
|
||||
log_debug("No version info on the host (rolling release?), but ID in %s matched.", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the extension has a sysext API level declared, then it must match the host API
|
||||
* level. Otherwise, compare OS version as a whole */
|
||||
extension_release_sysext_level = strv_env_pairs_get(extension_release, "SYSEXT_LEVEL");
|
||||
if (!isempty(host_os_release_sysext_level) && !isempty(extension_release_sysext_level)) {
|
||||
if (!streq_ptr(host_os_release_sysext_level, extension_release_sysext_level)) {
|
||||
log_debug("Extension '%s' is for sysext API level '%s', but running on sysext API level '%s'",
|
||||
name, strna(extension_release_sysext_level), strna(host_os_release_sysext_level));
|
||||
return 0;
|
||||
}
|
||||
} else if (!isempty(host_os_release_version_id)) {
|
||||
const char *extension_release_version_id;
|
||||
|
||||
extension_release_version_id = strv_env_pairs_get(extension_release, "VERSION_ID");
|
||||
if (isempty(extension_release_version_id)) {
|
||||
log_debug("Extension '%s' does not contain VERSION_ID in extension-release but requested to match '%s'",
|
||||
name, strna(host_os_release_version_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!streq_ptr(host_os_release_version_id, extension_release_version_id)) {
|
||||
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
|
||||
name, strna(extension_release_version_id), strna(host_os_release_version_id));
|
||||
return 0;
|
||||
}
|
||||
} else if (isempty(host_os_release_version_id) && isempty(host_os_release_sysext_level)) {
|
||||
/* Rolling releases do not typically set VERSION_ID (eg: ArchLinux) */
|
||||
log_debug("No version info on the host (rolling release?), but ID in %s matched.", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("Version info of extension '%s' matches host.", name);
|
||||
return 1;
|
||||
}
|
@ -6,6 +6,8 @@
|
||||
/* The *_extension_release flavours will look for /usr/lib/extension-release/extension-release.NAME
|
||||
* in accordance with the OS extension specification, rather than for /usr/lib/ or /etc/os-release. */
|
||||
|
||||
bool image_name_is_valid(const char *s) _pure_;
|
||||
|
||||
int path_is_extension_tree(const char *path, const char *extension);
|
||||
static inline int path_is_os_tree(const char *path) {
|
||||
return path_is_extension_tree(path, NULL);
|
||||
@ -21,13 +23,11 @@ static inline int fopen_os_release(const char *root, char **ret_path, FILE **ret
|
||||
return fopen_extension_release(root, NULL, ret_path, ret_file);
|
||||
}
|
||||
|
||||
int parse_extension_release(const char *root, const char *extension, ...) _sentinel_;
|
||||
int parse_os_release(const char *root, ...) _sentinel_;
|
||||
int _parse_extension_release(const char *root, const char *extension, ...) _sentinel_;
|
||||
int _parse_os_release(const char *root, ...) _sentinel_;
|
||||
#define parse_extension_release(root, extension, ...) _parse_extension_release(root, extension, __VA_ARGS__, NULL)
|
||||
#define parse_os_release(root, ...) _parse_os_release(root, __VA_ARGS__, NULL)
|
||||
|
||||
int load_extension_release_pairs(const char *root, const char *extension, char ***ret);
|
||||
int load_os_release_pairs(const char *root, char ***ret);
|
||||
int load_os_release_pairs_with_prefix(const char *root, const char *prefix, char ***ret);
|
||||
|
||||
/* Given an image name (for logging purposes), a set of os-release values from the host
|
||||
* and a key-value pair vector of extension-release variables, check that the distro and
|
||||
* (system extension level or distro version) match and return 1, and 0 otherwise. */
|
||||
int extension_release_validate(const char *name, const char *host_os_release_id, const char *host_os_release_version_id, const char *host_os_release_sysext_level, char **extension_release);
|
@ -5022,20 +5022,20 @@ int config_parse_mount_images(
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
r = unit_full_printf(u, first, &sresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", first);
|
||||
continue;
|
||||
}
|
||||
|
||||
s = sresolved;
|
||||
s = first;
|
||||
if (s[0] == '-') {
|
||||
permissive = true;
|
||||
s++;
|
||||
}
|
||||
|
||||
r = path_simplify_and_warn(s, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
|
||||
r = unit_full_printf(u, s, &sresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", s);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = path_simplify_and_warn(sresolved, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
@ -5113,7 +5113,7 @@ int config_parse_mount_images(
|
||||
|
||||
r = mount_image_add(&c->mount_images, &c->n_mount_images,
|
||||
&(MountImage) {
|
||||
.source = s,
|
||||
.source = sresolved,
|
||||
.destination = dresolved,
|
||||
.mount_options = options,
|
||||
.ignore_enoent = permissive,
|
||||
|
@ -134,6 +134,7 @@ static usec_t arg_kexec_watchdog;
|
||||
static char *arg_early_core_pattern;
|
||||
static char *arg_watchdog_device;
|
||||
static char **arg_default_environment;
|
||||
static char **arg_manager_environment;
|
||||
static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
|
||||
static uint64_t arg_capability_bounding_set;
|
||||
static bool arg_no_new_privs;
|
||||
@ -163,6 +164,36 @@ static char **saved_env = NULL;
|
||||
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
|
||||
const struct rlimit *saved_rlimit_memlock);
|
||||
|
||||
static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) {
|
||||
_cleanup_free_ char *base = NULL;
|
||||
_cleanup_strv_free_ char **files = NULL, **dirs = NULL;
|
||||
int r;
|
||||
|
||||
r = xdg_user_config_dir(&base, "/systemd");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extendf(&files, "%s/user.conf", base);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend(&files, PKGSYSCONFDIR "/user.conf");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_consume(&dirs, TAKE_PTR(base));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_extend_strv(&dirs, CONF_PATHS_STRV("systemd"), false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret_files = TAKE_PTR(files);
|
||||
*ret_dirs = TAKE_PTR(dirs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_noreturn_ static void freeze_or_exit_or_reboot(void) {
|
||||
|
||||
/* If we are running in a container, let's prefer exiting, after all we can propagate an exit code to
|
||||
@ -640,6 +671,7 @@ static int parse_config_file(void) {
|
||||
{ "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_default_start_limit_interval },
|
||||
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
|
||||
{ "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
|
||||
{ "Manager", "ManagerEnvironment", config_parse_environ, 0, &arg_manager_environment },
|
||||
{ "Manager", "DefaultLimitCPU", config_parse_rlimit, RLIMIT_CPU, arg_default_rlimit },
|
||||
{ "Manager", "DefaultLimitFSIZE", config_parse_rlimit, RLIMIT_FSIZE, arg_default_rlimit },
|
||||
{ "Manager", "DefaultLimitDATA", config_parse_rlimit, RLIMIT_DATA, arg_default_rlimit },
|
||||
@ -668,26 +700,34 @@ static int parse_config_file(void) {
|
||||
{}
|
||||
};
|
||||
|
||||
const char *fn, *conf_dirs_nulstr;
|
||||
_cleanup_strv_free_ char **_free_files = NULL, **_free_dirs = NULL;
|
||||
|
||||
fn = arg_system ?
|
||||
PKGSYSCONFDIR "/system.conf" :
|
||||
PKGSYSCONFDIR "/user.conf";
|
||||
const char *const *files, *const *dirs, *suffix;
|
||||
int r;
|
||||
|
||||
conf_dirs_nulstr = arg_system ?
|
||||
CONF_PATHS_NULSTR("systemd/system.conf.d") :
|
||||
CONF_PATHS_NULSTR("systemd/user.conf.d");
|
||||
if (arg_system) {
|
||||
files = STRV_MAKE_CONST(PKGSYSCONFDIR "/system.conf");
|
||||
dirs = (const char* const*) CONF_PATHS_STRV("systemd");
|
||||
suffix = "system.conf.d";
|
||||
} else {
|
||||
r = manager_find_user_config_paths(&_free_files, &_free_dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine config file paths: %m");
|
||||
files = (const char* const*) _free_files;
|
||||
dirs = (const char* const*) _free_dirs;
|
||||
suffix = "user.conf.d";
|
||||
}
|
||||
|
||||
(void) config_parse_many_nulstr(
|
||||
fn, conf_dirs_nulstr,
|
||||
(void) config_parse_many(
|
||||
files, dirs, suffix,
|
||||
"Manager\0",
|
||||
config_item_table_lookup, items,
|
||||
CONFIG_PARSE_WARN,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY
|
||||
* like everywhere else. */
|
||||
/* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use
|
||||
* USEC_INFINITY like everywhere else. */
|
||||
if (arg_default_timeout_start_usec <= 0)
|
||||
arg_default_timeout_start_usec = USEC_INFINITY;
|
||||
if (arg_default_timeout_stop_usec <= 0)
|
||||
@ -1312,8 +1352,7 @@ static int status_welcome(void) {
|
||||
|
||||
r = parse_os_release(NULL,
|
||||
"PRETTY_NAME", &pretty_name,
|
||||
"ANSI_COLOR", &ansi_color,
|
||||
NULL);
|
||||
"ANSI_COLOR", &ansi_color);
|
||||
if (r < 0)
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to read os-release file, ignoring: %m");
|
||||
@ -2263,6 +2302,19 @@ static void fallback_rlimit_memlock(const struct rlimit *saved_rlimit_memlock) {
|
||||
arg_default_rlimit[RLIMIT_MEMLOCK] = rl;
|
||||
}
|
||||
|
||||
static void setenv_manager_environment(void) {
|
||||
char **p;
|
||||
int r;
|
||||
|
||||
STRV_FOREACH(p, arg_manager_environment) {
|
||||
log_debug("Setting '%s' in our own environment.", *p);
|
||||
|
||||
r = putenv_dup(*p, true);
|
||||
if (r < 0)
|
||||
log_warning_errno(errno, "Failed to setenv \"%s\", ignoring: %m", *p);
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_arguments(void) {
|
||||
/* Frees/resets arg_* variables, with a few exceptions commented below. */
|
||||
|
||||
@ -2296,6 +2348,7 @@ static void reset_arguments(void) {
|
||||
arg_watchdog_device = NULL;
|
||||
|
||||
arg_default_environment = strv_free(arg_default_environment);
|
||||
arg_manager_environment = strv_free(arg_manager_environment);
|
||||
rlimit_free_all(arg_default_rlimit);
|
||||
|
||||
arg_capability_bounding_set = CAP_ALL;
|
||||
@ -2357,6 +2410,9 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
|
||||
if (arg_show_status == _SHOW_STATUS_INVALID)
|
||||
arg_show_status = SHOW_STATUS_YES;
|
||||
|
||||
/* Push variables into the manager environment block */
|
||||
setenv_manager_environment();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -106,8 +106,7 @@ static void print_welcome(void) {
|
||||
r = parse_os_release(
|
||||
arg_root,
|
||||
"PRETTY_NAME", &pretty_name,
|
||||
"ANSI_COLOR", &ansi_color,
|
||||
NULL);
|
||||
"ANSI_COLOR", &ansi_color);
|
||||
if (r < 0)
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to read os-release file, ignoring: %m");
|
||||
|
@ -159,8 +159,7 @@ static void context_read_os_release(Context *c) {
|
||||
r = parse_os_release(NULL,
|
||||
"PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
|
||||
"CPE_NAME", &c->data[PROP_OS_CPE_NAME],
|
||||
"HOME_URL", &c->data[PROP_OS_HOME_URL],
|
||||
NULL);
|
||||
"HOME_URL", &c->data[PROP_OS_HOME_URL]);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_warning_errno(r, "Failed to read os-release file, ignoring: %m");
|
||||
|
||||
@ -323,6 +322,7 @@ static int context_update_kernel_hostname(
|
||||
Context *c,
|
||||
const char *transient_hn) {
|
||||
|
||||
_cleanup_free_ char *_hn_free = NULL;
|
||||
const char *hn;
|
||||
HostnameSource hns;
|
||||
int r;
|
||||
@ -341,8 +341,11 @@ static int context_update_kernel_hostname(
|
||||
|
||||
/* ... and the ultimate fallback */
|
||||
} else {
|
||||
hn = FALLBACK_HOSTNAME;
|
||||
hns = HOSTNAME_FALLBACK;
|
||||
hn = _hn_free = get_default_hostname();
|
||||
if (!hn)
|
||||
return log_oom();
|
||||
|
||||
hns = HOSTNAME_DEFAULT;
|
||||
}
|
||||
|
||||
r = sethostname_idempotent(hn);
|
||||
@ -503,16 +506,20 @@ static int property_get_hostname(
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_free_ char *current = NULL;
|
||||
_cleanup_free_ char *hn = NULL;
|
||||
int r;
|
||||
|
||||
r = gethostname_strict(¤t);
|
||||
if (r == -ENXIO)
|
||||
return sd_bus_message_append(reply, "s", FALLBACK_HOSTNAME);
|
||||
if (r < 0)
|
||||
r = gethostname_strict(&hn);
|
||||
if (r < 0) {
|
||||
if (r != -ENXIO)
|
||||
return r;
|
||||
|
||||
return sd_bus_message_append(reply, "s", current);
|
||||
hn = get_default_hostname();
|
||||
if (!hn)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "s", hn);
|
||||
}
|
||||
|
||||
static int property_get_static_hostname(
|
||||
@ -532,7 +539,21 @@ static int property_get_static_hostname(
|
||||
return sd_bus_message_append(reply, "s", c->data[PROP_STATIC_HOSTNAME]);
|
||||
}
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_fallback_hostname, "s", FALLBACK_HOSTNAME);
|
||||
static int property_get_default_hostname(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_free_ char *hn = get_default_hostname();
|
||||
if (!hn)
|
||||
return log_oom();
|
||||
|
||||
return sd_bus_message_append(reply, "s", hn);
|
||||
}
|
||||
|
||||
static int property_get_hostname_source(
|
||||
sd_bus *bus,
|
||||
@ -560,16 +581,16 @@ static int property_get_hostname_source(
|
||||
|
||||
else {
|
||||
/* If the hostname was not set by us, try to figure out where it came from. If we set
|
||||
* it to the fallback hostname, the file will tell us. We compare the string because
|
||||
* it to the default hostname, the file will tell us. We compare the string because
|
||||
* it is possible that the hostname was set by an older version that had a different
|
||||
* fallback, in the initramfs or before we reexecuted. */
|
||||
|
||||
r = read_one_line_file("/run/systemd/fallback-hostname", &fallback);
|
||||
r = read_one_line_file("/run/systemd/default-hostname", &fallback);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_warning_errno(r, "Failed to read /run/systemd/fallback-hostname, ignoring: %m");
|
||||
log_warning_errno(r, "Failed to read /run/systemd/default-hostname, ignoring: %m");
|
||||
|
||||
if (streq_ptr(fallback, hostname))
|
||||
c->hostname_source = HOSTNAME_FALLBACK;
|
||||
c->hostname_source = HOSTNAME_DEFAULT;
|
||||
else
|
||||
c->hostname_source = HOSTNAME_TRANSIENT;
|
||||
}
|
||||
@ -967,7 +988,7 @@ static const sd_bus_vtable hostname_vtable[] = {
|
||||
SD_BUS_PROPERTY("Hostname", "s", property_get_hostname, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("StaticHostname", "s", property_get_static_hostname, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("PrettyHostname", "s", property_get_machine_info_field, offsetof(Context, data) + sizeof(char*) * PROP_PRETTY_HOSTNAME, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("FallbackHostname", "s", property_get_fallback_hostname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultHostname", "s", property_get_default_hostname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("HostnameSource", "s", property_get_hostname_source, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IconName", "s", property_get_icon_name, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("Chassis", "s", property_get_chassis, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
|
@ -755,7 +755,7 @@ static int request_handler_machine(
|
||||
if (r < 0)
|
||||
return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %m");
|
||||
|
||||
(void) parse_os_release(NULL, "PRETTY_NAME", &os_name, NULL);
|
||||
(void) parse_os_release(NULL, "PRETTY_NAME", &os_name);
|
||||
(void) get_virtualization(&v);
|
||||
|
||||
r = asprintf(&json,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "loop-util.h"
|
||||
#include "missing_capability.h"
|
||||
#include "mount-util.h"
|
||||
#include "os-util.h"
|
||||
#include "process-util.h"
|
||||
#include "raw-clone.h"
|
||||
#include "strv.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "machine-pool.h"
|
||||
#include "machined.h"
|
||||
#include "missing_capability.h"
|
||||
#include "os-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "stdio-util.h"
|
||||
|
@ -686,7 +686,7 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
||||
|
||||
dropin_dirname = strjoina(basename(filename), ".d");
|
||||
r = config_parse_many(
|
||||
filename, NETWORK_DIRS, dropin_dirname,
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname,
|
||||
NETDEV_COMMON_SECTIONS NETDEV_OTHER_SECTIONS,
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
@ -729,7 +729,7 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
||||
NETDEV_VTABLE(netdev)->init(netdev);
|
||||
|
||||
r = config_parse_many(
|
||||
filename, NETWORK_DIRS, dropin_dirname,
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname,
|
||||
NETDEV_VTABLE(netdev)->sections,
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
|
@ -446,7 +446,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||
};
|
||||
|
||||
r = config_parse_many(
|
||||
filename, NETWORK_DIRS, dropin_dirname,
|
||||
STRV_MAKE_CONST(filename), NETWORK_DIRS, dropin_dirname,
|
||||
"Match\0"
|
||||
"Link\0"
|
||||
"SR-IOV\0"
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "bus-wait-for-jobs.h"
|
||||
#include "def.h"
|
||||
#include "dirent-util.h"
|
||||
#include "discover-image.h"
|
||||
#include "env-file.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@ -20,6 +19,7 @@
|
||||
#include "fs-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "main-func.h"
|
||||
#include "os-util.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "missing_capability.h"
|
||||
#include "os-util.h"
|
||||
#include "portable.h"
|
||||
#include "portabled-bus.h"
|
||||
#include "portabled-image-bus.h"
|
||||
|
@ -1,7 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
"Generate %-from-name.gperf from %-list.txt"
|
||||
"""Generate %-from-name.gperf from %-list.txt
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
@ -13,12 +14,12 @@ print("""\
|
||||
_Pragma("GCC diagnostic ignored \\"-Wimplicit-fallthrough\\"")
|
||||
#endif
|
||||
%}""")
|
||||
print(f"""\
|
||||
struct {name}_name {{ const char* name; int id; }};
|
||||
print("""\
|
||||
struct {}_name {{ const char* name; int id; }};
|
||||
%null-strings
|
||||
%%""")
|
||||
%%""".format(name))
|
||||
|
||||
for line in open(input):
|
||||
line = line.rstrip()
|
||||
s = line.replace('_', '-')
|
||||
print(f'{s}, {prefix}{line}')
|
||||
print("{}, {}{}".format(s, prefix, line))
|
||||
|
@ -668,7 +668,7 @@ int dns_answer_copy_by_key(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dns_answer_add(*a, item->rr, item->ifindex, item->flags|or_flags, item->rrsig);
|
||||
r = dns_answer_add(*a, item->rr, item->ifindex, item->flags|or_flags, rrsig ?: item->rrsig);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ typedef enum DnsAnswerFlags {
|
||||
DNS_ANSWER_SECTION_ANSWER = 1 << 5, /* When parsing: RR originates from answer section */
|
||||
DNS_ANSWER_SECTION_AUTHORITY = 1 << 6, /* When parsing: RR originates from authority section */
|
||||
DNS_ANSWER_SECTION_ADDITIONAL = 1 << 7, /* When parsing: RR originates from additional section */
|
||||
|
||||
DNS_ANSWER_MASK_SECTIONS = DNS_ANSWER_SECTION_ANSWER|
|
||||
DNS_ANSWER_SECTION_AUTHORITY|
|
||||
DNS_ANSWER_SECTION_ADDITIONAL,
|
||||
} DnsAnswerFlags;
|
||||
|
||||
struct DnsAnswerItem {
|
||||
|
@ -1140,3 +1140,10 @@ bool dns_query_fully_confidential(DnsQuery *q) {
|
||||
|
||||
return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) && !q->previous_redirect_non_confidential;
|
||||
}
|
||||
|
||||
bool dns_query_fully_synthetic(DnsQuery *q) {
|
||||
assert(q);
|
||||
|
||||
return (q->answer_query_flags & (SD_RESOLVED_SYNTHETIC | SD_RESOLVED_FROM_TRUST_ANCHOR)) &&
|
||||
!(q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~SD_RESOLVED_FROM_TRUST_ANCHOR);
|
||||
}
|
||||
|
@ -134,6 +134,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
|
||||
|
||||
bool dns_query_fully_authenticated(DnsQuery *q);
|
||||
bool dns_query_fully_confidential(DnsQuery *q);
|
||||
bool dns_query_fully_synthetic(DnsQuery *q);
|
||||
|
||||
static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
|
||||
assert(q);
|
||||
|
@ -1722,6 +1722,7 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl) {
|
||||
}
|
||||
|
||||
bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
|
||||
assert(rr);
|
||||
|
||||
if (rr->key->class != DNS_CLASS_IN)
|
||||
return false;
|
||||
@ -1735,6 +1736,47 @@ bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret) {
|
||||
_cleanup_free_ char *d = NULL;
|
||||
int r;
|
||||
|
||||
assert(key);
|
||||
assert(cname);
|
||||
|
||||
if (key->class != cname->key->class && key->class != DNS_CLASS_ANY)
|
||||
return -EUNATCH;
|
||||
|
||||
if (cname->key->type == DNS_TYPE_CNAME) {
|
||||
r = dns_name_equal(dns_resource_key_name(key),
|
||||
dns_resource_key_name(cname->key));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EUNATCH; /* CNAME RR key doesn't actually match the original key */
|
||||
|
||||
d = strdup(cname->cname.name);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
} else if (cname->key->type == DNS_TYPE_DNAME) {
|
||||
|
||||
r = dns_name_change_suffix(
|
||||
dns_resource_key_name(key),
|
||||
dns_resource_key_name(cname->key),
|
||||
cname->dname.name,
|
||||
&d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return -EUNATCH; /* DNAME RR key doesn't actually match the original key */
|
||||
|
||||
} else
|
||||
return -EUNATCH; /* Not a CNAME/DNAME RR, hence doesn't match the proposition either */
|
||||
|
||||
*ret = TAKE_PTR(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i) {
|
||||
DnsTxtItem *n;
|
||||
|
||||
|
@ -326,6 +326,8 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl);
|
||||
|
||||
bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr);
|
||||
|
||||
int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord *cname, char **ret);
|
||||
|
||||
DnsTxtItem *dns_txt_item_free_all(DnsTxtItem *i);
|
||||
bool dns_txt_item_equal(DnsTxtItem *a, DnsTxtItem *b);
|
||||
DnsTxtItem *dns_txt_item_copy(DnsTxtItem *i);
|
||||
|
@ -883,6 +883,7 @@ int dns_scope_make_reply_packet(
|
||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
||||
unsigned n_answer = 0, n_soa = 0;
|
||||
int r;
|
||||
bool c_or_aa;
|
||||
|
||||
assert(s);
|
||||
assert(ret);
|
||||
@ -896,11 +897,14 @@ int dns_scope_make_reply_packet(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* mDNS answers must have the Authoritative Answer bit set, see RFC 6762, section 18.4. */
|
||||
c_or_aa = s->protocol == DNS_PROTOCOL_MDNS;
|
||||
|
||||
DNS_PACKET_HEADER(p)->id = id;
|
||||
DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
|
||||
1 /* qr */,
|
||||
0 /* opcode */,
|
||||
0 /* c */,
|
||||
c_or_aa,
|
||||
0 /* tc */,
|
||||
tentative,
|
||||
0 /* (ra) */,
|
||||
|
@ -139,12 +139,38 @@ static int stub_packet_compare_func(const DnsPacket *x, const DnsPacket *y) {
|
||||
|
||||
DEFINE_HASH_OPS(stub_packet_hash_ops, DnsPacket, stub_packet_hash_func, stub_packet_compare_func);
|
||||
|
||||
static int reply_add_with_rrsig(
|
||||
DnsAnswer **reply,
|
||||
DnsResourceRecord *rr,
|
||||
int ifindex,
|
||||
DnsAnswerFlags flags,
|
||||
DnsResourceRecord *rrsig,
|
||||
bool with_rrsig) {
|
||||
int r;
|
||||
|
||||
assert(reply);
|
||||
assert(rr);
|
||||
|
||||
r = dns_answer_add_extend(reply, rr, ifindex, flags, rrsig);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (with_rrsig && rrsig) {
|
||||
r = dns_answer_add_extend(reply, rrsig, ifindex, flags, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dns_stub_collect_answer_by_question(
|
||||
DnsAnswer **reply,
|
||||
DnsAnswer *answer,
|
||||
DnsQuestion *question,
|
||||
bool with_rrsig) { /* Add RRSIG RR matching each RR */
|
||||
|
||||
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *redirected_key = NULL;
|
||||
DnsAnswerItem *item;
|
||||
int r;
|
||||
|
||||
@ -153,36 +179,71 @@ static int dns_stub_collect_answer_by_question(
|
||||
/* Copies all RRs from 'answer' into 'reply', if they match 'question'. */
|
||||
|
||||
DNS_ANSWER_FOREACH_ITEM(item, answer) {
|
||||
|
||||
if (question) {
|
||||
bool match = false;
|
||||
|
||||
r = dns_question_matches_rr(question, item->rr, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if (r > 0)
|
||||
match = true;
|
||||
else {
|
||||
r = dns_question_matches_cname_or_dname(question, item->rr, NULL);
|
||||
if (r == 0) {
|
||||
_cleanup_free_ char *target = NULL;
|
||||
|
||||
/* OK, so the RR doesn't directly match. Let's see if the RR is a matching
|
||||
* CNAME or DNAME */
|
||||
|
||||
r = dns_resource_record_get_cname_target(
|
||||
question->keys[0],
|
||||
item->rr,
|
||||
&target);
|
||||
if (r == -EUNATCH)
|
||||
continue; /* Not a CNAME/DNAME or doesn't match */
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
match = true;
|
||||
|
||||
dns_resource_key_unref(redirected_key);
|
||||
|
||||
/* There can only be one CNAME per name, hence no point in storing more than one here */
|
||||
redirected_key = dns_resource_key_new(question->keys[0]->class, question->keys[0]->type, target);
|
||||
if (!redirected_key)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match)
|
||||
/* Mask the section info, we want the primary answers to always go without section info, so
|
||||
* that it is added to the answer section when we synthesize a reply. */
|
||||
|
||||
r = reply_add_with_rrsig(
|
||||
reply,
|
||||
item->rr,
|
||||
item->ifindex,
|
||||
item->flags & ~DNS_ANSWER_MASK_SECTIONS,
|
||||
item->rrsig,
|
||||
with_rrsig);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!redirected_key)
|
||||
return 0;
|
||||
|
||||
/* This is a CNAME/DNAME answer. In this case also append where the redirections point to to the main
|
||||
* answer section */
|
||||
|
||||
DNS_ANSWER_FOREACH_ITEM(item, answer) {
|
||||
|
||||
r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
r = dns_answer_add_extend(reply, item->rr, item->ifindex, item->flags, item->rrsig);
|
||||
r = reply_add_with_rrsig(
|
||||
reply,
|
||||
item->rr,
|
||||
item->ifindex,
|
||||
item->flags & ~DNS_ANSWER_MASK_SECTIONS,
|
||||
item->rrsig,
|
||||
with_rrsig);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (with_rrsig && item->rrsig) {
|
||||
r = dns_answer_add_extend(reply, item->rrsig, item->ifindex, item->flags, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -197,7 +258,6 @@ static int dns_stub_collect_answer_by_section(
|
||||
bool with_dnssec) { /* Include DNSSEC RRs. RRSIG, NSEC, … */
|
||||
|
||||
DnsAnswerItem *item;
|
||||
unsigned c = 0;
|
||||
int r;
|
||||
|
||||
assert(reply);
|
||||
@ -218,22 +278,18 @@ static int dns_stub_collect_answer_by_section(
|
||||
if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
|
||||
continue;
|
||||
|
||||
r = dns_answer_add_extend(reply, item->rr, item->ifindex, item->flags, item->rrsig);
|
||||
r = reply_add_with_rrsig(
|
||||
reply,
|
||||
item->rr,
|
||||
item->ifindex,
|
||||
item->flags,
|
||||
item->rrsig,
|
||||
with_dnssec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c++;
|
||||
|
||||
if (with_dnssec && item->rrsig) {
|
||||
r = dns_answer_add_extend(reply, item->rrsig, item->ifindex, item->flags, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
return (int) c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dns_stub_assign_sections(
|
||||
@ -246,17 +302,17 @@ static int dns_stub_assign_sections(
|
||||
assert(q);
|
||||
assert(question);
|
||||
|
||||
/* Let's assign the 'answer' and 'answer_auxiliary' RRs we collected to their respective sections in
|
||||
* the reply datagram. We try to reproduce a section assignment similar to what the upstream DNS
|
||||
* server responded to us. We use the DNS_ANSWER_SECTION_xyz flags to match things up, which is where
|
||||
* the original upstream's packet section assignment is stored in the DnsAnswer object. Not all RRs
|
||||
* in the 'answer' and 'answer_auxiliary' objects come with section information though (for example,
|
||||
* because they were synthesized locally, and not from a DNS packet). To deal with that we extend the
|
||||
* assignment logic a bit: anything from the 'answer' object that directly matches the original
|
||||
* question is always put in the ANSWER section, regardless if it carries section info, or what that
|
||||
* section info says. Then, anything from the 'answer' and 'answer_auxiliary' objects that is from
|
||||
* the ANSWER or AUTHORITY sections, and wasn't already added to the ANSWER section is placed in the
|
||||
* AUTHORITY section. Everything else from either object is added to the ADDITIONAL section. */
|
||||
/* Let's assign the 'answer' RRs we collected to their respective sections in the reply datagram. We
|
||||
* try to reproduce a section assignment similar to what the upstream DNS server responded to us. We
|
||||
* use the DNS_ANSWER_SECTION_xyz flags to match things up, which is where the original upstream's
|
||||
* packet section assignment is stored in the DnsAnswer object. Not all RRs in the 'answer' objects
|
||||
* come with section information though (for example, because they were synthesized locally, and not
|
||||
* from a DNS packet). To deal with that we extend the assignment logic a bit: anything from the
|
||||
* 'answer' object that directly matches the original question is always put in the ANSWER section,
|
||||
* regardless if it carries section info, or what that section info says. Then, anything from the
|
||||
* 'answer' objects that is from the ANSWER or AUTHORITY sections, and wasn't already added to the
|
||||
* ANSWER section is placed in the AUTHORITY section. Everything else from either object is added to
|
||||
* the ADDITIONAL section. */
|
||||
|
||||
/* Include all RRs that directly answer the question in the answer section */
|
||||
r = dns_stub_collect_answer_by_question(
|
||||
@ -277,9 +333,6 @@ static int dns_stub_assign_sections(
|
||||
edns0_do);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Include all RRs that originate from the answer or authority sections, and aren't listed in the
|
||||
* answer section, in the authority section */
|
||||
r = dns_stub_collect_answer_by_section(
|
||||
&q->reply_authoritative,
|
||||
q->answer,
|
||||
@ -428,6 +481,7 @@ static int dns_stub_finish_reply_packet(
|
||||
uint16_t id,
|
||||
int rcode,
|
||||
bool tc, /* set the Truncated bit? */
|
||||
bool aa, /* set the Authoritative Answer bit? */
|
||||
bool add_opt, /* add an OPT RR to this packet? */
|
||||
bool edns0_do, /* set the EDNS0 DNSSEC OK bit? */
|
||||
bool ad, /* set the DNSSEC authenticated data bit? */
|
||||
@ -466,7 +520,7 @@ static int dns_stub_finish_reply_packet(
|
||||
DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
|
||||
1 /* qr */,
|
||||
0 /* opcode */,
|
||||
0 /* aa */,
|
||||
aa /* aa */,
|
||||
tc /* tc */,
|
||||
1 /* rd */,
|
||||
1 /* ra */,
|
||||
@ -556,6 +610,7 @@ static int dns_stub_send_reply(
|
||||
DNS_PACKET_ID(q->request_packet),
|
||||
rcode,
|
||||
truncated,
|
||||
dns_query_fully_synthetic(q),
|
||||
!!q->request_packet->opt,
|
||||
edns0_do,
|
||||
DNS_PACKET_AD(q->request_packet) && dns_query_fully_authenticated(q),
|
||||
@ -596,6 +651,7 @@ static int dns_stub_send_failure(
|
||||
DNS_PACKET_ID(p),
|
||||
rcode,
|
||||
truncated,
|
||||
false,
|
||||
!!p->opt,
|
||||
DNS_PACKET_DO(p),
|
||||
DNS_PACKET_AD(p) && authenticated,
|
||||
@ -681,27 +737,13 @@ static void dns_stub_query_complete(DnsQuery *q) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Note that we don't bother with following CNAMEs here. We propagate the authoritative/additional
|
||||
* sections from the upstream answer however, hence if the upstream server collected that information
|
||||
* already we don't have to collect it ourselves anymore. */
|
||||
|
||||
switch (q->state) {
|
||||
|
||||
case DNS_TRANSACTION_SUCCESS:
|
||||
/* Follow CNAMEs, and accumulate answers. Except if DNSSEC is requested, then let the client do that. */
|
||||
if (!DNS_PACKET_DO(q->request_packet)) {
|
||||
r = dns_query_process_cname(q);
|
||||
if (r == -ELOOP) { /* CNAME loop */
|
||||
(void) dns_stub_send_reply(q, DNS_RCODE_SERVFAIL);
|
||||
break;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to process CNAME: %m");
|
||||
break;
|
||||
}
|
||||
if (r == DNS_QUERY_RESTARTED)
|
||||
return;
|
||||
}
|
||||
|
||||
(void) dns_stub_send_reply(q, q->answer_rcode);
|
||||
break;
|
||||
|
||||
case DNS_TRANSACTION_RCODE_FAILURE:
|
||||
(void) dns_stub_send_reply(q, q->answer_rcode);
|
||||
break;
|
||||
@ -840,7 +882,8 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
|
||||
r = dns_query_new(m, &q, p->question, p->question, NULL, 0,
|
||||
SD_RESOLVED_PROTOCOLS_ALL|
|
||||
SD_RESOLVED_NO_SEARCH|
|
||||
(DNS_PACKET_DO(p) ? SD_RESOLVED_NO_CNAME|SD_RESOLVED_REQUIRE_PRIMARY : 0)|
|
||||
SD_RESOLVED_NO_CNAME|
|
||||
(DNS_PACKET_DO(p) ? SD_RESOLVED_REQUIRE_PRIMARY : 0)|
|
||||
SD_RESOLVED_CLAMP_TTL);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to generate query object: %m");
|
||||
|
@ -88,7 +88,7 @@ static int dnssd_service_load(Manager *manager, const char *filename) {
|
||||
dropin_dirname = strjoina(service->name, ".dnssd.d");
|
||||
|
||||
r = config_parse_many(
|
||||
filename, DNSSD_SERVICE_DIRS, dropin_dirname,
|
||||
STRV_MAKE_CONST(filename), DNSSD_SERVICE_DIRS, dropin_dirname,
|
||||
"Service\0",
|
||||
config_item_perf_lookup, resolved_dnssd_gperf_lookup,
|
||||
CONFIG_PARSE_WARN,
|
||||
|
@ -442,20 +442,25 @@ static int determine_hostname(char **full_hostname, char **llmnr_hostname, char
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *fallback_hostname(void) {
|
||||
static char* fallback_hostname(void) {
|
||||
|
||||
/* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it to be
|
||||
* "localhost" even if that's the compiled in hostname. In this case, let's revert to "linux" instead. */
|
||||
/* Determine the fall back hostname. For exposing this system to the outside world, we cannot have it
|
||||
* to be "localhost" even if that's the default hostname. In this case, let's revert to "linux"
|
||||
* instead. */
|
||||
|
||||
if (is_localhost(FALLBACK_HOSTNAME))
|
||||
return "linux";
|
||||
_cleanup_free_ char *n = get_default_hostname();
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
return FALLBACK_HOSTNAME;
|
||||
if (is_localhost(n))
|
||||
return strdup("linux");
|
||||
|
||||
return TAKE_PTR(n);
|
||||
}
|
||||
|
||||
static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname, char **mdns_hostname) {
|
||||
_cleanup_free_ char *n = NULL, *m = NULL;
|
||||
char label[DNS_LABEL_MAX], *h;
|
||||
_cleanup_free_ char *h = NULL, *n = NULL, *m = NULL;
|
||||
char label[DNS_LABEL_MAX];
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
@ -463,7 +468,10 @@ static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname,
|
||||
assert(llmnr_hostname);
|
||||
assert(mdns_hostname);
|
||||
|
||||
p = fallback_hostname();
|
||||
p = h = fallback_hostname();
|
||||
if (!h)
|
||||
return log_oom();
|
||||
|
||||
r = dns_label_unescape(&p, label, sizeof label, 0);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to unescape fallback hostname: %m");
|
||||
@ -478,14 +486,9 @@ static int make_fallback_hostnames(char **full_hostname, char **llmnr_hostname,
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to concatenate mDNS hostname: %m");
|
||||
|
||||
h = strdup(fallback_hostname());
|
||||
if (!h)
|
||||
return log_oom();
|
||||
|
||||
*llmnr_hostname = TAKE_PTR(n);
|
||||
*mdns_hostname = TAKE_PTR(m);
|
||||
|
||||
*full_hostname = h;
|
||||
*full_hostname = TAKE_PTR(h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -90,8 +90,41 @@ static void test_packet_from_file(const char* filename, bool canonical) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_dns_resource_record_get_cname_target(void) {
|
||||
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *dname = NULL;
|
||||
_cleanup_free_ char *target = NULL;
|
||||
|
||||
assert_se(cname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_CNAME, "quux.foobar"));
|
||||
assert_se(cname->cname.name = strdup("wuff.wuff"));
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "waldo"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "foobar"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, ""), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "."), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "nope.quux.foobar"), cname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux.foobar"), cname, &target) == 0);
|
||||
assert_se(streq(target, "wuff.wuff"));
|
||||
target = mfree(target);
|
||||
|
||||
assert_se(dname = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_DNAME, "quux.foobar"));
|
||||
assert_se(dname->dname.name = strdup("wuff.wuff"));
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "waldo"), dname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "foobar"), dname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux"), dname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, ""), dname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "."), dname, &target) == -EUNATCH);
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "yupp.quux.foobar"), dname, &target) == 0);
|
||||
assert_se(streq(target, "yupp.wuff.wuff"));
|
||||
target = mfree(target);
|
||||
|
||||
assert_se(dns_resource_record_get_cname_target(&DNS_RESOURCE_KEY_CONST(DNS_CLASS_IN, DNS_TYPE_A, "quux.foobar"), cname, &target) == 0);
|
||||
assert_se(streq(target, "wuff.wuff"));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, N;
|
||||
int N;
|
||||
_cleanup_globfree_ glob_t g = {};
|
||||
char **fnames;
|
||||
|
||||
@ -108,7 +141,7 @@ int main(int argc, char **argv) {
|
||||
fnames = g.gl_pathv;
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
for (int i = 0; i < N; i++) {
|
||||
test_packet_from_file(fnames[i], false);
|
||||
puts("");
|
||||
test_packet_from_file(fnames[i], true);
|
||||
@ -116,5 +149,7 @@ int main(int argc, char **argv) {
|
||||
puts("");
|
||||
}
|
||||
|
||||
test_dns_resource_record_get_cname_target();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -354,6 +354,15 @@ static int condition_test_control_group_controller(Condition *c, char **env) {
|
||||
assert(c->parameter);
|
||||
assert(c->type == CONDITION_CONTROL_GROUP_CONTROLLER);
|
||||
|
||||
if (streq(c->parameter, "v2"))
|
||||
return cg_all_unified();
|
||||
if (streq(c->parameter, "v1")) {
|
||||
r = cg_all_unified();
|
||||
if (r < 0)
|
||||
return r;
|
||||
return !r;
|
||||
}
|
||||
|
||||
r = cg_mask_supported(&system_mask);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine supported controllers: %m");
|
||||
|
@ -420,11 +420,11 @@ int config_parse(
|
||||
if (ret_mtime)
|
||||
*ret_mtime = mtime;
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parse_many_files(
|
||||
const char *conf_file,
|
||||
const char* const* conf_files,
|
||||
char **files,
|
||||
const char *sections,
|
||||
ConfigItemLookup lookup,
|
||||
@ -437,20 +437,23 @@ static int config_parse_many_files(
|
||||
char **fn;
|
||||
int r;
|
||||
|
||||
if (conf_file) {
|
||||
r = config_parse(NULL, conf_file, NULL, sections, lookup, table, flags, userdata, &mtime);
|
||||
/* First read the first found main config file. */
|
||||
STRV_FOREACH(fn, (char**) conf_files) {
|
||||
r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &mtime);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Then read all the drop-ins. */
|
||||
STRV_FOREACH(fn, files) {
|
||||
usec_t t;
|
||||
|
||||
r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (t > mtime) /* Find the newest */
|
||||
mtime = t;
|
||||
mtime = MAX(mtime, t); /* Find the newest */
|
||||
}
|
||||
|
||||
if (ret_mtime)
|
||||
@ -477,12 +480,14 @@ int config_parse_many_nulstr(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
|
||||
return config_parse_many_files(STRV_MAKE_CONST(conf_file),
|
||||
files, sections, lookup, table, flags, userdata,
|
||||
ret_mtime);
|
||||
}
|
||||
|
||||
/* Parse each config file in the directories specified as strv. */
|
||||
int config_parse_many(
|
||||
const char *conf_file,
|
||||
const char* const* conf_files,
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *sections,
|
||||
@ -506,7 +511,7 @@ int config_parse_many(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return config_parse_many_files(conf_file, files, sections, lookup, table, flags, userdata, ret_mtime);
|
||||
return config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_mtime);
|
||||
}
|
||||
|
||||
#define DEFINE_PARSER(type, vartype, conv_func) \
|
||||
|
@ -102,7 +102,7 @@ int config_parse_many_nulstr(
|
||||
usec_t *ret_mtime); /* possibly NULL */
|
||||
|
||||
int config_parse_many(
|
||||
const char *conf_file, /* possibly NULL */
|
||||
const char* const* conf_files, /* possibly empty */
|
||||
const char* const* conf_file_dirs,
|
||||
const char *dropin_dirname,
|
||||
const char *sections, /* nulstr */
|
||||
|
@ -1250,23 +1250,6 @@ int image_name_lock(const char *name, int operation, LockFile *ret) {
|
||||
return make_lock_file(p, operation, ret);
|
||||
}
|
||||
|
||||
bool image_name_is_valid(const char *s) {
|
||||
if (!filename_is_valid(s))
|
||||
return false;
|
||||
|
||||
if (string_has_cc(s, NULL))
|
||||
return false;
|
||||
|
||||
if (!utf8_is_valid(s))
|
||||
return false;
|
||||
|
||||
/* Temporary files for atomically creating new files */
|
||||
if (startswith(s, ".#"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool image_in_search_path(
|
||||
ImageClass class,
|
||||
const char *root,
|
||||
|
@ -76,8 +76,6 @@ int image_read_only(Image *i, bool b);
|
||||
const char* image_type_to_string(ImageType t) _const_;
|
||||
ImageType image_type_from_string(const char *s) _pure_;
|
||||
|
||||
bool image_name_is_valid(const char *s) _pure_;
|
||||
|
||||
int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local);
|
||||
int image_name_lock(const char *name, int operation, LockFile *ret);
|
||||
|
||||
|
79
src/shared/extension-release.c
Normal file
79
src/shared/extension-release.c
Normal file
@ -0,0 +1,79 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "env-util.h"
|
||||
#include "extension-release.h"
|
||||
#include "log.h"
|
||||
#include "os-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
int extension_release_validate(
|
||||
const char *name,
|
||||
const char *host_os_release_id,
|
||||
const char *host_os_release_version_id,
|
||||
const char *host_os_release_sysext_level,
|
||||
char **extension_release) {
|
||||
|
||||
const char *extension_release_id = NULL, *extension_release_sysext_level = NULL;
|
||||
|
||||
assert(name);
|
||||
assert(!isempty(host_os_release_id));
|
||||
|
||||
/* Now that we can look into the extension image, let's see if the OS version is compatible */
|
||||
if (strv_isempty(extension_release)) {
|
||||
log_debug("Extension '%s' carries no extension-release data, ignoring extension.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extension_release_id = strv_env_pairs_get(extension_release, "ID");
|
||||
if (isempty(extension_release_id)) {
|
||||
log_debug("Extension '%s' does not contain ID in extension-release but requested to match '%s'",
|
||||
name, strna(host_os_release_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!streq_ptr(host_os_release_id, extension_release_id)) {
|
||||
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
|
||||
name, strna(extension_release_id), strna(host_os_release_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Rolling releases do not typically set VERSION_ID (eg: ArchLinux) */
|
||||
if (isempty(host_os_release_version_id) && isempty(host_os_release_sysext_level)) {
|
||||
log_debug("No version info on the host (rolling release?), but ID in %s matched.", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the extension has a sysext API level declared, then it must match the host API
|
||||
* level. Otherwise, compare OS version as a whole */
|
||||
extension_release_sysext_level = strv_env_pairs_get(extension_release, "SYSEXT_LEVEL");
|
||||
if (!isempty(host_os_release_sysext_level) && !isempty(extension_release_sysext_level)) {
|
||||
if (!streq_ptr(host_os_release_sysext_level, extension_release_sysext_level)) {
|
||||
log_debug("Extension '%s' is for sysext API level '%s', but running on sysext API level '%s'",
|
||||
name, strna(extension_release_sysext_level), strna(host_os_release_sysext_level));
|
||||
return 0;
|
||||
}
|
||||
} else if (!isempty(host_os_release_version_id)) {
|
||||
const char *extension_release_version_id;
|
||||
|
||||
extension_release_version_id = strv_env_pairs_get(extension_release, "VERSION_ID");
|
||||
if (isempty(extension_release_version_id)) {
|
||||
log_debug("Extension '%s' does not contain VERSION_ID in extension-release but requested to match '%s'",
|
||||
name, strna(host_os_release_version_id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!streq_ptr(host_os_release_version_id, extension_release_version_id)) {
|
||||
log_debug("Extension '%s' is for OS '%s', but deployed on top of '%s'.",
|
||||
name, strna(extension_release_version_id), strna(host_os_release_version_id));
|
||||
return 0;
|
||||
}
|
||||
} else if (isempty(host_os_release_version_id) && isempty(host_os_release_sysext_level)) {
|
||||
/* Rolling releases do not typically set VERSION_ID (eg: ArchLinux) */
|
||||
log_debug("No version info on the host (rolling release?), but ID in %s matched.", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("Version info of extension '%s' matches host.", name);
|
||||
return 1;
|
||||
}
|
12
src/shared/extension-release.h
Normal file
12
src/shared/extension-release.h
Normal file
@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* Given an image name (for logging purposes), a set of os-release values from the host and a key-value pair
|
||||
* vector of extension-release variables, check that the distro and (system extension level or distro
|
||||
* version) match and return 1, and 0 otherwise. */
|
||||
int extension_release_validate(
|
||||
const char *name,
|
||||
const char *host_os_release_id,
|
||||
const char *host_os_release_version_id,
|
||||
const char *host_os_release_sysext_level,
|
||||
char **extension_release);
|
@ -152,13 +152,13 @@ void hostname_update_source_hint(const char *hostname, HostnameSource source) {
|
||||
* notice if somebody sets the hostname directly (not going through hostnamed).
|
||||
*/
|
||||
|
||||
if (source == HOSTNAME_FALLBACK) {
|
||||
r = write_string_file("/run/systemd/fallback-hostname", hostname,
|
||||
if (source == HOSTNAME_DEFAULT) {
|
||||
r = write_string_file("/run/systemd/default-hostname", hostname,
|
||||
WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_ATOMIC);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to create \"/run/systemd/fallback-hostname\": %m");
|
||||
log_warning_errno(r, "Failed to create \"/run/systemd/default-hostname\": %m");
|
||||
} else
|
||||
unlink_or_warn("/run/systemd/fallback-hostname");
|
||||
unlink_or_warn("/run/systemd/default-hostname");
|
||||
}
|
||||
|
||||
int hostname_setup(bool really) {
|
||||
@ -194,7 +194,7 @@ int hostname_setup(bool really) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isempty(hn)) {
|
||||
if (!hn) {
|
||||
/* Don't override the hostname if it is already set and not explicitly configured */
|
||||
|
||||
char buf[HOST_NAME_MAX + 1] = {};
|
||||
@ -204,10 +204,13 @@ int hostname_setup(bool really) {
|
||||
}
|
||||
|
||||
if (enoent)
|
||||
log_info("No hostname configured, using fallback hostname.");
|
||||
log_info("No hostname configured, using default hostname.");
|
||||
|
||||
hn = FALLBACK_HOSTNAME;
|
||||
source = HOSTNAME_FALLBACK;
|
||||
hn = b = get_default_hostname();
|
||||
if (!hn)
|
||||
return log_oom();
|
||||
|
||||
source = HOSTNAME_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
@ -230,7 +233,7 @@ int hostname_setup(bool really) {
|
||||
static const char* const hostname_source_table[] = {
|
||||
[HOSTNAME_STATIC] = "static",
|
||||
[HOSTNAME_TRANSIENT] = "transient",
|
||||
[HOSTNAME_FALLBACK] = "fallback",
|
||||
[HOSTNAME_DEFAULT] = "default",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(hostname_source, HostnameSource);
|
||||
|
@ -7,7 +7,7 @@
|
||||
typedef enum HostnameSource {
|
||||
HOSTNAME_STATIC, /* from /etc/hostname */
|
||||
HOSTNAME_TRANSIENT, /* a transient hostname set through systemd, hostnamed, the container manager, or otherwise */
|
||||
HOSTNAME_FALLBACK, /* the compiled-in fallback was used */
|
||||
HOSTNAME_DEFAULT, /* the os-release default or the compiled-in fallback were used */
|
||||
_HOSTNAME_INVALID = -EINVAL,
|
||||
} HostnameSource;
|
||||
|
||||
|
@ -100,6 +100,8 @@ shared_sources = files('''
|
||||
exec-util.h
|
||||
exit-status.c
|
||||
exit-status.h
|
||||
extension-release.c
|
||||
extension-release.h
|
||||
fdset.c
|
||||
fdset.h
|
||||
fileio-label.c
|
||||
@ -196,8 +198,6 @@ shared_sources = files('''
|
||||
numa-util.h
|
||||
openssl-util.c
|
||||
openssl-util.h
|
||||
os-util.c
|
||||
os-util.h
|
||||
output-mode.c
|
||||
output-mode.h
|
||||
pager.c
|
||||
|
@ -203,7 +203,7 @@ static int specifier_os_release_common(const char *field, char **ret) {
|
||||
char *t = NULL;
|
||||
int r;
|
||||
|
||||
r = parse_os_release(NULL, field, &t, NULL);
|
||||
r = parse_os_release(NULL, field, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (!t) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "dissect-image.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "extension-release.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "format-table.h"
|
||||
@ -472,8 +473,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
|
||||
arg_root,
|
||||
"ID", &host_os_release_id,
|
||||
"VERSION_ID", &host_os_release_version_id,
|
||||
"SYSEXT_LEVEL", &host_os_release_sysext_level,
|
||||
NULL);
|
||||
"SYSEXT_LEVEL", &host_os_release_sysext_level);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire 'os-release' data of OS tree '%s': %m", empty_to_root(arg_root));
|
||||
|
||||
|
@ -18,9 +18,9 @@ for line in open(sys.argv[1]):
|
||||
if match:
|
||||
s = match.group(1)
|
||||
if s == 'sd_bus_object_vtable_format':
|
||||
print(f' &{s},')
|
||||
print(' &{},'.format(s))
|
||||
else:
|
||||
print(f' {s},')
|
||||
print(' {},'.format(s))
|
||||
|
||||
print('''};
|
||||
|
||||
|
@ -124,10 +124,26 @@ static void test_condition_test_path(void) {
|
||||
condition_free(condition);
|
||||
}
|
||||
|
||||
static void test_condition_test_control_group_hierarchy(void) {
|
||||
Condition *condition;
|
||||
int r;
|
||||
|
||||
r = cg_unified();
|
||||
|
||||
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v1", false, false);
|
||||
assert_se(condition);
|
||||
assert_se(condition_test(condition, environ) == (r < CGROUP_UNIFIED_ALL));
|
||||
condition_free(condition);
|
||||
|
||||
condition = condition_new(CONDITION_CONTROL_GROUP_CONTROLLER, "v2", false, false);
|
||||
assert_se(condition);
|
||||
assert_se(condition_test(condition, environ) == (r >= CGROUP_UNIFIED_ALL));
|
||||
condition_free(condition);
|
||||
}
|
||||
|
||||
static void test_condition_test_control_group_controller(void) {
|
||||
Condition *condition;
|
||||
CGroupMask system_mask;
|
||||
CGroupController controller;
|
||||
_cleanup_free_ char *controller_name = NULL;
|
||||
int r;
|
||||
|
||||
@ -151,7 +167,7 @@ static void test_condition_test_control_group_controller(void) {
|
||||
assert_se(cg_mask_supported(&system_mask) >= 0);
|
||||
|
||||
/* Individual valid controllers one by one */
|
||||
for (controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
|
||||
for (CGroupController controller = 0; controller < _CGROUP_CONTROLLER_MAX; controller++) {
|
||||
const char *local_controller_name = cgroup_controller_to_string(controller);
|
||||
log_info("chosen controller is '%s'", local_controller_name);
|
||||
if (system_mask & CGROUP_CONTROLLER_TO_MASK(controller)) {
|
||||
@ -881,6 +897,7 @@ int main(int argc, char *argv[]) {
|
||||
test_condition_test_virtualization();
|
||||
test_condition_test_user();
|
||||
test_condition_test_group();
|
||||
test_condition_test_control_group_hierarchy();
|
||||
test_condition_test_control_group_controller();
|
||||
test_condition_test_cpus();
|
||||
test_condition_test_memory();
|
||||
|
@ -349,27 +349,27 @@ static void test_config_parse(unsigned i, const char *s) {
|
||||
|
||||
switch (i) {
|
||||
case 0 ... 4:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, "1"));
|
||||
break;
|
||||
|
||||
case 5 ... 10:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, "1 2 3"));
|
||||
break;
|
||||
|
||||
case 11:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, "1\\\\ \\\\2"));
|
||||
break;
|
||||
|
||||
case 12:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, x1000("ABCD")));
|
||||
break;
|
||||
|
||||
case 13 ... 14:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, x1000("ABCD") " foobar"));
|
||||
break;
|
||||
|
||||
@ -379,7 +379,7 @@ static void test_config_parse(unsigned i, const char *s) {
|
||||
break;
|
||||
|
||||
case 17:
|
||||
assert_se(r == 0);
|
||||
assert_se(r == 1);
|
||||
assert_se(streq(setting1, "2"));
|
||||
break;
|
||||
}
|
||||
|
@ -361,6 +361,19 @@ static void test_env_assignment_is_valid(void) {
|
||||
assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
|
||||
}
|
||||
|
||||
static void test_putenv_dup(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(putenv_dup("A=a1", true) == 0);
|
||||
assert_se(streq(getenv("A"), "a1"));
|
||||
assert_se(putenv_dup("A=a1", true) == 0);
|
||||
assert_se(streq(getenv("A"), "a1"));
|
||||
assert_se(putenv_dup("A=a2", false) == 0);
|
||||
assert_se(streq(getenv("A"), "a1"));
|
||||
assert_se(putenv_dup("A=a2", true) == 0);
|
||||
assert_se(streq(getenv("A"), "a2"));
|
||||
}
|
||||
|
||||
static void test_setenv_systemd_exec_pid(void) {
|
||||
_cleanup_free_ char *saved = NULL;
|
||||
const char *e;
|
||||
@ -416,6 +429,7 @@ int main(int argc, char *argv[]) {
|
||||
test_env_name_is_valid();
|
||||
test_env_value_is_valid();
|
||||
test_env_assignment_is_valid();
|
||||
test_putenv_dup();
|
||||
test_setenv_systemd_exec_pid();
|
||||
|
||||
return 0;
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
static void test_hostname_is_valid(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(hostname_is_valid("foobar", 0));
|
||||
assert_se(hostname_is_valid("foobar.com", 0));
|
||||
assert_se(!hostname_is_valid("foobar.com.", 0));
|
||||
@ -49,6 +51,8 @@ static void test_hostname_is_valid(void) {
|
||||
static void test_hostname_cleanup(void) {
|
||||
char *s;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
s = strdupa("foobar");
|
||||
assert_se(streq(hostname_cleanup(s), "foobar"));
|
||||
s = strdupa("foobar.com");
|
||||
@ -94,6 +98,8 @@ static void test_hostname_cleanup(void) {
|
||||
static void test_hostname_malloc(void) {
|
||||
_cleanup_free_ char *h = NULL, *l = NULL;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(h = gethostname_malloc());
|
||||
log_info("hostname_malloc: \"%s\"", h);
|
||||
|
||||
@ -101,21 +107,27 @@ static void test_hostname_malloc(void) {
|
||||
log_info("hostname_short_malloc: \"%s\"", l);
|
||||
}
|
||||
|
||||
static void test_fallback_hostname(void) {
|
||||
static void test_default_hostname(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
if (!hostname_is_valid(FALLBACK_HOSTNAME, 0)) {
|
||||
log_error("Configured fallback hostname \"%s\" is not valid.", FALLBACK_HOSTNAME);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_cleanup_free_ char *n = get_default_hostname();
|
||||
assert_se(n);
|
||||
log_info("get_default_hostname: \"%s\"", n);
|
||||
assert_se(hostname_is_valid(n, 0));
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_INFO);
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_hostname_is_valid();
|
||||
test_hostname_cleanup();
|
||||
test_hostname_malloc();
|
||||
|
||||
test_fallback_hostname();
|
||||
test_default_hostname();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user