Compare commits

...

28 Commits

Author SHA1 Message Date
Luca Boccassi d904afc730 core: reload cache if it's dirty when starting a UNIT_NOT_FOUND unit
The time-based cache allows starting a new unit without an expensive
daemon-reload, unless there was already a reference to it because of
a dependency or ordering from another unit.
If the cache is out of date, check again if we can load the
fragment.
2020-05-30 16:50:05 +02:00
Zbigniew Jędrzejewski-Szmek 956508cb5d
Merge pull request #15935 from poettering/cache-more-efi-vars
logind + efi-loader: cache more efi vars
2020-05-30 15:44:26 +02:00
Rafael Fontenelle d308cd4bfa po: update Brazilian Portuguese translation 2020-05-30 15:21:48 +02:00
Zbigniew Jędrzejewski-Szmek 3a02643a40
Merge pull request #15915 from poettering/journal-external-link
journal: show external links in log output
2020-05-30 15:04:40 +02:00
Daan De Meyer 366d077235 update NEWS 2020-05-30 14:31:24 +02:00
Lennart Poettering ddb82ec2a2 sd-dhcp: clean-up of DHCP lease server code
This is an attempt to clean-up the DHCP lease server type code a bit. We
now strictly use the same enum everywhere, and store server info in an
array. Moreover, we use the same nomenclature everywhere.

This only makes the changes in the sd-dhcp code. The networkd code is
untouched so far (but should be fixed up like this too. But it's more
complicated since this would then touch actual settings in .network
files).

Note that this also changes some field names in serialized lease files.
But given that these field names have not been part of a released
version of systemd yet, such a change should be ok.

This is pure renaming/refactoring, shouldn't actually change any
behaviour.
2020-05-30 14:18:43 +02:00
Jay Burger eed44b715d fix_test_function_timeout 2020-05-30 12:01:29 +02:00
Christian Oder 5e0676c2ca hwdb: Add accel orientation quirk for Chuwi Hi10 X
Add a quirk to fix the accelerometer orientation on the Chuwi Hi10 X
so that the display is not rotated 90 degree counter clockwise anymore.
2020-05-30 11:59:47 +02:00
Susant Sahani a1422af564 network: L2TP fix crash
```
=220358== Invalid read of size 8
==220358==    at 0x452F05: l2tp_session_free (l2tp-tunnel.c:46)
==220358==    by 0x456926: l2tp_tunnel_done (l2tp-tunnel.c:725)
==220358==    by 0x43CF4D: netdev_free (netdev.c:205)
==220358==    by 0x43D045: netdev_unref (netdev.c:210)
==220358==    by 0x4198B7: manager_free (networkd-manager.c:1877)
==220358==    by 0x40D0B3: manager_freep (networkd-manager.h:105)
==220358==    by 0x40DE1C: run (networkd.c:21)
==220358==    by 0x40DE75: main (networkd.c:130)
==220358==  Address 0x5c035d0 is 0 bytes inside a block of size 40 free'd
==220358==    at 0x483A9F5: free (vg_replace_malloc.c:538)
==220358==    by 0x452F87: l2tp_session_free (l2tp-tunnel.c:57)
==220358==    by 0x456857: netdev_l2tp_tunnel_verify (l2tp-tunnel.c:710)
==220358==    by 0x440947: netdev_load_one (netdev.c:738)
==220358==    by 0x441222: netdev_load (netdev.c:851)
==220358==    by 0x419C50: manager_load_config (networkd-manager.c:1934)
==220358==    by 0x40D7BE: run (networkd.c:87)
==220358==    by 0x40DE75: main (networkd.c:130)
==220358==  Block was alloc'd at
==220358==    at 0x4839809: malloc (vg_replace_malloc.c:307)
==220358==    by 0x452A76: malloc_multiply (alloc-util.h:96)
==220358==    by 0x4531E6: l2tp_session_new_static (l2tp-tunnel.c:82)
==220358==    by 0x455C01: config_parse_l2tp_session_id (l2tp-tunnel.c:535)
==220358==    by 0x48E6D72: next_assignment (conf-parser.c:133)
==220358==    by 0x48E77A3: parse_line (conf-parser.c:271)
==220358==    by 0x48E7E4F: config_parse (conf-parser.c:396)
==220358==    by 0x48E80E5: config_parse_many_files (conf-parser.c:453)
==220358==    by 0x48E8490: config_parse_many (conf-parser.c:512)
==220358==    by 0x44089C: netdev_load_one (netdev.c:729)
==220358==    by 0x441222: netdev_load (netdev.c:851)
==220358==    by 0x419C50: manager_load_config (networkd-manager.c:1934)

```
2020-05-30 11:59:27 +02:00
Daan De Meyer 269412ef44
Merge pull request #15958 from layderv/master
#15773 add --reboot-arg to systemctl reboot
2020-05-30 11:04:14 +02:00
Daan De Meyer 02591c95bb
Merge pull request #15975 from mgub/patch-1
Fix typo.
2020-05-30 11:00:13 +02:00
Michael Gubbels bf1abf1a2c
Fix typo. 2020-05-29 16:40:39 -07:00
laydervus dae710bef1 #15773 add --reboot-argument to systemctl reboot 2020-05-29 21:22:29 +01:00
Lennart Poettering 84190644ff efi: add more logging for all EFI variable reads 2020-05-29 15:42:09 +02:00
Lennart Poettering 002914e688 bootctl: add simple, low-level reboot-to-firmware verb for controlling the flag 2020-05-29 15:41:50 +02:00
Lennart Poettering 8a96369e0b bootctl: show reboot-to-firmware info, too 2020-05-29 15:41:46 +02:00
Lennart Poettering c37070c85a efi: cache OsIndications too 2020-05-29 15:41:43 +02:00
Lennart Poettering d197c403b2 efi: explicitly update mtime of EFI variables when changing them 2020-05-29 15:41:31 +02:00
Lennart Poettering c75e7da0b5 efi: as extra paranoia NUL terminate UTF-16 strings with three NUL bytes
This is a safey net anyway, let's make it fully safe: if the data ends
on an uneven byte, then we need to complete the UTF-16 codepoint first,
before adding the final NUL byte pair. Hence let's suffix with three
NULs, instead of just two.
2020-05-29 15:41:18 +02:00
Lennart Poettering 9e5230aad9 efi: cache OsIndicationsSupported
As suggested by:

https://github.com/systemd/systemd/issues/14828#issuecomment-634202054
2020-05-29 15:41:06 +02:00
Lennart Poettering 5c25f42322 efi: avoid weirdly double }} by indenting differently 2020-05-29 15:41:03 +02:00
Lennart Poettering d4bd786d69 efi: cache LoaderEntries EFI variable
Based-on:

https://github.com/systemd/systemd/issues/14828#issuecomment-634202054
2020-05-29 15:40:01 +02:00
Lennart Poettering dd587c3a88 man: briefly document the DOCUMENTATION= structure log field 2020-05-29 10:41:30 +02:00
Lennart Poettering 2fac514fa9 logs: strndupa() cannot fail 2020-05-29 10:41:30 +02:00
Lennart Poettering 2108b56749 journal: show documentation hyperlink if known in log output 2020-05-29 10:41:30 +02:00
Lennart Poettering 422c8251e5 pretty-print: export urlify_enabled() 2020-05-29 10:41:30 +02:00
Lennart Poettering a90fb08c81 locale-util: add glyph for external links 2020-05-29 10:41:30 +02:00
Lennart Poettering b965ec7a63 catalog: normalize how we link to documentation 2020-05-29 10:41:30 +02:00
48 changed files with 772 additions and 450 deletions

8
NEWS
View File

@ -122,6 +122,10 @@ CHANGES WITH 246 in spe:
sd_bus_member_name_is_valid() + sd_bus_object_path_is_valid() will 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. 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 * systemctl gained a new "-P" switch that is a shortcut for "--value
--property=…". --property=…".
@ -349,6 +353,10 @@ CHANGES WITH 246 in spe:
the default) an address from any acquire delegated prefix is the default) an address from any acquire delegated prefix is
automatically chosen and assigned to the interface. 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.
CHANGES WITH 245: CHANGES WITH 245:
* A new tool "systemd-repart" has been added, that operates as an * A new tool "systemd-repart" has been added, that operates as an

View File

@ -302,7 +302,8 @@ shut down.
Subject: DNSSEC mode has been turned off, as server doesn't support it Subject: DNSSEC mode has been turned off, as server doesn't support it
Defined-By: systemd Defined-By: systemd
Support: %SUPPORT_URL% Support: %SUPPORT_URL%
Documentation: man:systemd-resolved.service(8) resolved.conf(5) Documentation: man:systemd-resolved.service(8)
Documentation: man:resolved.conf(5)
The resolver service (systemd-resolved.service) has detected that the The resolver service (systemd-resolved.service) has detected that the
configured DNS server does not support DNSSEC, and DNSSEC validation has been configured DNS server does not support DNSSEC, and DNSSEC validation has been
@ -417,6 +418,7 @@ Note that the memory pressure might or might not have been caused by @UNIT@.
Subject: Accepting user/group name @USER_GROUP_NAME@, which does not match strict user/group name rules. Subject: Accepting user/group name @USER_GROUP_NAME@, which does not match strict user/group name rules.
Defined-By: systemd Defined-By: systemd
Support: %SUPPORT_URL% Support: %SUPPORT_URL%
Documentation: https://systemd.io/USER_NAMES
The user/group name @USER_GROUP_NAME@ has been specified, which is accepted The user/group name @USER_GROUP_NAME@ has been specified, which is accepted
according the relaxed user/group name rules, but does not qualify under the according the relaxed user/group name rules, but does not qualify under the
@ -432,10 +434,6 @@ characters; names not valid UTF-8; names with leading or trailing whitespace;
the strings "." or ".."; fully numeric strings, or strings beginning in a the strings "." or ".."; fully numeric strings, or strings beginning in a
hyphen and otherwise fully numeric. hyphen and otherwise fully numeric.
For further details on strict and relaxed user/group name rules, see:
https://systemd.io/USER_NAMES
-- 1b3bb94037f04bbf81028e135a12d293 -- 1b3bb94037f04bbf81028e135a12d293
Subject: Failed to generate valid unit name from path '@MOUNT_POINT@'. Subject: Failed to generate valid unit name from path '@MOUNT_POINT@'.
Defined-By: systemd Defined-By: systemd

View File

@ -180,6 +180,10 @@ sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvrP02A_C106.60E:*:
sensor:modalias:acpi:BOSC0200*:dmi:*:svn*CHUWIINNOVATIONANDTECHNOLOGY*:pnHi10protablet:* sensor:modalias:acpi:BOSC0200*:dmi:*:svn*CHUWIINNOVATIONANDTECHNOLOGY*:pnHi10protablet:*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
# Chuwi Hi10 X
sensor:modalias:acpi:MXC6655*:dmi:*:svnCHUWIInnovationAndTechnology*:pnHi10X:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
# Chuwi Hi12 # Chuwi Hi12
sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnP02BD6_HI-122LP:* sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo:pnP02BD6_HI-122LP:*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1

View File

@ -102,7 +102,7 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>systemd-efi-options</option> <optional><replaceable>VALUE</replaceable></optional></term> <term><option>systemd-efi-options</option> <optional><replaceable>STRING</replaceable></optional></term>
<listitem><para>When called without the optional argument, prints the current value of the <listitem><para>When called without the optional argument, prints the current value of the
<literal>SystemdOptions</literal> EFI variable. When called with an argument, sets the <literal>SystemdOptions</literal> EFI variable. When called with an argument, sets the
@ -111,6 +111,17 @@
for the meaning of that variable.</para></listitem> for the meaning of that variable.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>reboot-to-firmware</option> <optional><replaceable>BOOL</replaceable></optional></term>
<listitem><para>Query or set the "Reboot-Into-Firmware-Setup" flag of the EFI firmware. Takes a
boolean argument which controls whether to show the firmware setup on next system reboot. If the
argument is omitted shows the current status of the flag, or whether the flag is supported. This
controls the same flag as <command>systemctl reboot --firmware-setup</command>, but is more
low-level and allows setting the flag independently from actually requesting a
reboot.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>list</option></term> <term><option>list</option></term>

View File

@ -1295,7 +1295,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><command>reboot</command> <optional><replaceable>arg</replaceable></optional></term> <term><command>reboot</command></term>
<listitem> <listitem>
<para>Shut down and reboot the system. This is mostly equivalent to <command>systemctl start reboot.target <para>Shut down and reboot the system. This is mostly equivalent to <command>systemctl start reboot.target
@ -1311,11 +1311,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<command>systemctl</command> itself, and the system manager is not contacted. This means the command should <command>systemctl</command> itself, and the system manager is not contacted. This means the command should
succeed even when the system manager has crashed.</para> succeed even when the system manager has crashed.</para>
<para>If the optional argument <replaceable>arg</replaceable> is given, it will be passed as the optional <para>If the switch <option>--reboot-argument=</option> is given, it will be passed as the optional
argument to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> argument to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
system call. The value is architecture and firmware specific. As an example, <literal>recovery</literal> system call.</para>
might be used to trigger system recovery, and <literal>fota</literal> might be used to trigger a
<quote>firmware over the air</quote> update.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2117,6 +2115,16 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--reboot-argument=</option></term>
<listitem>
<para>This switch is used with <command>reboot</command>. The value is architecture and firmware specific. As an example, <literal>recovery</literal>
might be used to trigger system recovery, and <literal>fota</literal> might be used to trigger a
<quote>firmware over the air</quote> update.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--plain</option></term> <term><option>--plain</option></term>

View File

@ -139,6 +139,16 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>DOCUMENTATION=</varname></term>
<listitem>
<para>A documentation URL with further information about the topic of the log message. Tools such
as <command>journalctl</command> will include a hyperlink to an URL specified this way in their
output. Should be a <literal>http://</literal>, <literal>https://</literal>,
<literal>file:/</literal>, <literal>man:</literal> or <literal>info:</literal> URL.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -1284,7 +1284,7 @@
<term><varname>ConditionNeedsUpdate=</varname></term> <term><varname>ConditionNeedsUpdate=</varname></term>
<listitem><para>Takes one of <filename>/var</filename> or <filename>/etc</filename> as argument, <listitem><para>Takes one of <filename>/var</filename> or <filename>/etc</filename> as argument,
possibly prefixed with a <literal>!</literal> (to inverting the condition). This condition may be possibly prefixed with a <literal>!</literal> (to invert the condition). This condition may be
used to conditionalize units on whether the specified directory requires an update because used to conditionalize units on whether the specified directory requires an update because
<filename>/usr</filename>'s modification time is newer than the stamp file <filename>/usr</filename>'s modification time is newer than the stamp file
<filename>.updated</filename> in the specified directory. This is useful to implement offline <filename>.updated</filename> in the specified directory. This is useful to implement offline

View File

@ -3,14 +3,14 @@
# Brazilian Portuguese translation for systemd. # Brazilian Portuguese translation for systemd.
# Enrico Nicoletto <liverig@gmail.com>, 2014. # Enrico Nicoletto <liverig@gmail.com>, 2014.
# Filipe Brandenburger <filbranden@gmail.com>, 2018. # Filipe Brandenburger <filbranden@gmail.com>, 2018.
# Rafael Fontenelle <rafaelff@gnome.org>, 2015-2019. # Rafael Fontenelle <rafaelff@gnome.org>, 2015-2020.
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: systemd\n" "Project-Id-Version: systemd\n"
"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n" "Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
"POT-Creation-Date: 2019-09-08 15:28+0000\n" "POT-Creation-Date: 2020-05-29 03:32+0000\n"
"PO-Revision-Date: 2019-09-08 19:00-0300\n" "PO-Revision-Date: 2020-05-30 09:10-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n" "Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n" "Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n" "Language: pt_BR\n"
@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n" "Plural-Forms: nplurals=2; plural=(n > 1)\n"
"X-Generator: Gtranslator 3.32.0\n" "X-Generator: Gtranslator 3.36.0\n"
#: src/core/org.freedesktop.systemd1.policy.in:22 #: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system" msgid "Send passphrase back to system"
@ -73,13 +73,67 @@ msgstr "Recarregar o estado do sistema"
msgid "Authentication is required to reload the systemd state." msgid "Authentication is required to reload the systemd state."
msgstr "É necessária autenticação para recarregar o estado do sistema." msgstr "É necessária autenticação para recarregar o estado do sistema."
#: src/home/org.freedesktop.home1.policy:13
msgid "Create a home area"
msgstr "Criar uma área home"
#: src/home/org.freedesktop.home1.policy:14
msgid "Authentication is required to create a user's home area."
msgstr "É necessária autenticação para criar a área home de um usuário."
#: src/home/org.freedesktop.home1.policy:23
msgid "Remove a home area"
msgstr "Remover uma área home"
#: src/home/org.freedesktop.home1.policy:24
msgid "Authentication is required to remove a user's home area."
msgstr "É necessária autenticação para remover a área home de um usuário."
#: src/home/org.freedesktop.home1.policy:33
msgid "Check credentials of a home area"
msgstr "Verificar credenciais de uma área home"
#: src/home/org.freedesktop.home1.policy:34
msgid ""
"Authentication is required to check credentials against a user's home area."
msgstr ""
"É necessária autenticação para verificar credenciais da área home de um "
"usuário."
#: src/home/org.freedesktop.home1.policy:43
msgid "Update a home area"
msgstr "Atualizar uma área home"
#: src/home/org.freedesktop.home1.policy:44
msgid "Authentication is required to update a user's home area."
msgstr "É necessária autenticação para atualizar a área home de um usuário."
#: src/home/org.freedesktop.home1.policy:53
msgid "Resize a home area"
msgstr "Redimensionar uma área home"
#: src/home/org.freedesktop.home1.policy:54
msgid "Authentication is required to resize a user's home area."
msgstr ""
"É necessária autenticação para redimensionar a área home de um usuário."
#: src/home/org.freedesktop.home1.policy:63
msgid "Change password of a home area"
msgstr "Alterar senha de uma área home"
#: src/home/org.freedesktop.home1.policy:64
msgid ""
"Authentication is required to change the password of a user's home area."
msgstr ""
"É necessária autenticação para alterar a senha da área home de um usuário."
#: src/hostname/org.freedesktop.hostname1.policy:20 #: src/hostname/org.freedesktop.hostname1.policy:20
msgid "Set hostname" msgid "Set hostname"
msgstr "Definir nome de máquina" msgstr "Definir nome de máquina"
#: src/hostname/org.freedesktop.hostname1.policy:21 #: src/hostname/org.freedesktop.hostname1.policy:21
msgid "Authentication is required to set the local hostname." msgid "Authentication is required to set the local hostname."
msgstr "É necessária autenticação para definir nome de máquina local." msgstr "É necessária autenticação para definir o nome de máquina local."
#: src/hostname/org.freedesktop.hostname1.policy:30 #: src/hostname/org.freedesktop.hostname1.policy:30
msgid "Set static hostname" msgid "Set static hostname"
@ -293,8 +347,7 @@ msgid "Flush device to seat attachments"
msgstr "Liberar dispositivo para conexões da estação" msgstr "Liberar dispositivo para conexões da estação"
#: src/login/org.freedesktop.login1.policy:149 #: src/login/org.freedesktop.login1.policy:149
msgid "" msgid "Authentication is required to reset how devices are attached to seats."
"Authentication is required to reset how devices are attached to seats."
msgstr "" msgstr ""
"É necessária autenticação para redefinir a quantidade de dispositivos " "É necessária autenticação para redefinir a quantidade de dispositivos "
"conectados na estação." "conectados na estação."
@ -325,8 +378,8 @@ msgstr "Desligar o sistema enquanto um aplicativo solicitou inibição"
#: src/login/org.freedesktop.login1.policy:181 #: src/login/org.freedesktop.login1.policy:181
msgid "" msgid ""
"Authentication is required to power off the system while an application " "Authentication is required to power off the system while an application is "
"is inhibiting this." "inhibiting this."
msgstr "" msgstr ""
"É necessária autenticação para desligar o sistema enquanto um aplicativo " "É necessária autenticação para desligar o sistema enquanto um aplicativo "
"solicitou inibição." "solicitou inibição."
@ -345,8 +398,8 @@ msgstr "Reiniciar o sistema enquanto outros usuários estiverem conectados"
#: src/login/org.freedesktop.login1.policy:203 #: src/login/org.freedesktop.login1.policy:203
msgid "" msgid ""
"Authentication is required to reboot the system while other users are " "Authentication is required to reboot the system while other users are logged "
"logged in." "in."
msgstr "" msgstr ""
"É necessária autenticação para reiniciar o sistema enquanto outros usuários " "É necessária autenticação para reiniciar o sistema enquanto outros usuários "
"estiverem conectados." "estiverem conectados."
@ -357,8 +410,8 @@ msgstr "Reiniciar o sistema enquanto um aplicativo solicitou inibição"
#: src/login/org.freedesktop.login1.policy:214 #: src/login/org.freedesktop.login1.policy:214
msgid "" msgid ""
"Authentication is required to reboot the system while an application " "Authentication is required to reboot the system while an application is "
"is inhibiting this." "inhibiting this."
msgstr "" msgstr ""
"É necessária autenticação para reiniciar o sistema enquanto um aplicativo " "É necessária autenticação para reiniciar o sistema enquanto um aplicativo "
"solicitou inibição." "solicitou inibição."
@ -377,8 +430,8 @@ msgstr "Parar o sistema enquanto outros usuários estão logados"
#: src/login/org.freedesktop.login1.policy:236 #: src/login/org.freedesktop.login1.policy:236
msgid "" msgid ""
"Authentication is required to halt the system while other users are " "Authentication is required to halt the system while other users are logged "
"logged in." "in."
msgstr "" msgstr ""
"É necessária autenticação para parar o sistema enquanto outros usuários " "É necessária autenticação para parar o sistema enquanto outros usuários "
"estejam logados." "estejam logados."
@ -389,8 +442,8 @@ msgstr "Parar o sistema enquanto um aplicativo solicitou inibição"
#: src/login/org.freedesktop.login1.policy:247 #: src/login/org.freedesktop.login1.policy:247
msgid "" msgid ""
"Authentication is required to halt the system while an application asked " "Authentication is required to halt the system while an application is "
"to inhibit it." "inhibiting this."
msgstr "" msgstr ""
"É necessária autenticação para parar o sistema enquanto um aplicativo " "É necessária autenticação para parar o sistema enquanto um aplicativo "
"solicitou inibição." "solicitou inibição."
@ -421,8 +474,8 @@ msgstr "Suspender o sistema enquanto um aplicativo solicitou inibição"
#: src/login/org.freedesktop.login1.policy:279 #: src/login/org.freedesktop.login1.policy:279
msgid "" msgid ""
"Authentication is required to suspend the system while an application " "Authentication is required to suspend the system while an application is "
"is inhibiting this." "inhibiting this."
msgstr "" msgstr ""
"É necessária autenticação para suspender o sistema enquanto um aplicativo " "É necessária autenticação para suspender o sistema enquanto um aplicativo "
"solicitou inibição." "solicitou inibição."
@ -453,8 +506,8 @@ msgstr "Hibernar o sistema enquanto um aplicativo solicitou inibição"
#: src/login/org.freedesktop.login1.policy:311 #: src/login/org.freedesktop.login1.policy:311
msgid "" msgid ""
"Authentication is required to hibernate the system while an application " "Authentication is required to hibernate the system while an application is "
"is inhibiting this." "inhibiting this."
msgstr "" msgstr ""
"É necessária autenticação para hibernar o sistema enquanto um aplicativo " "É necessária autenticação para hibernar o sistema enquanto um aplicativo "
"solicitou inibição." "solicitou inibição."
@ -464,8 +517,7 @@ msgid "Manage active sessions, users and seats"
msgstr "Gerenciar estações, usuários e sessões ativas" msgstr "Gerenciar estações, usuários e sessões ativas"
#: src/login/org.freedesktop.login1.policy:322 #: src/login/org.freedesktop.login1.policy:322
msgid "" msgid "Authentication is required to manage active sessions, users and seats."
"Authentication is required to manage active sessions, users and seats."
msgstr "" msgstr ""
"É necessária autenticação para gerenciar estações, usuários e sessões ativas." "É necessária autenticação para gerenciar estações, usuários e sessões ativas."
@ -509,7 +561,7 @@ msgid ""
"boot loader menu." "boot loader menu."
msgstr "" msgstr ""
"É necessária autenticação para indicar para o carregador de inicialização " "É necessária autenticação para indicar para o carregador de inicialização "
"iniciar seu menu" "iniciar seu menu."
#: src/login/org.freedesktop.login1.policy:374 #: src/login/org.freedesktop.login1.policy:374
msgid "Indicate to the boot loader to boot a specific entry" msgid "Indicate to the boot loader to boot a specific entry"
@ -522,7 +574,7 @@ msgid ""
"specific boot loader entry." "specific boot loader entry."
msgstr "" msgstr ""
"É necessária autenticação para indicar para o carregador de inicializar " "É necessária autenticação para indicar para o carregador de inicializar "
"iniciar uma entrada específica" "iniciar uma entrada específica."
#: src/login/org.freedesktop.login1.policy:385 #: src/login/org.freedesktop.login1.policy:385
msgid "Set a wall message" msgid "Set a wall message"
@ -532,6 +584,14 @@ msgstr "Definir uma mensagem de parede"
msgid "Authentication is required to set a wall message" msgid "Authentication is required to set a wall message"
msgstr "É necessária autenticação para definir uma mensagem de parede" msgstr "É necessária autenticação para definir uma mensagem de parede"
#: src/login/org.freedesktop.login1.policy:395
msgid "Change Session"
msgstr "Alterar sessão"
#: src/login/org.freedesktop.login1.policy:396
msgid "Authentication is required to change the virtual terminal."
msgstr "É necessária autenticação para alterar o terminal virtual."
#: src/machine/org.freedesktop.machine1.policy:22 #: src/machine/org.freedesktop.machine1.policy:22
msgid "Log into a local container" msgid "Log into a local container"
msgstr "Conectar a um contêiner local" msgstr "Conectar a um contêiner local"
@ -701,16 +761,48 @@ msgid "Revert NTP settings"
msgstr "Reverter configurações de NTP" msgstr "Reverter configurações de NTP"
#: src/network/org.freedesktop.network1.policy:122 #: src/network/org.freedesktop.network1.policy:122
msgid "Authentication is required to revert NTP settings." msgid "Authentication is required to reset NTP settings."
msgstr "É necessária autenticação para reverter as configurações de NTP." msgstr "É necessária autenticação para redefinir as configurações de NTP."
#: src/network/org.freedesktop.network1.policy:132 #: src/network/org.freedesktop.network1.policy:132
msgid "Revert DNS settings" msgid "Revert DNS settings"
msgstr "Reverter configurações de DNS" msgstr "Reverter configurações de DNS"
#: src/network/org.freedesktop.network1.policy:133 #: src/network/org.freedesktop.network1.policy:133
msgid "Authentication is required to revert DNS settings." msgid "Authentication is required to reset DNS settings."
msgstr "É necessária autenticação para reverter as configurações de DNS." msgstr "É necessária autenticação para redefinir as configurações de DNS."
#: src/network/org.freedesktop.network1.policy:143
msgid "DHCP server sends force renew message"
msgstr "Servidor DHCP envia mensagem de renovação forçada"
#: src/network/org.freedesktop.network1.policy:144
msgid "Authentication is required to send force renew message."
msgstr "É necessária autenticação para enviar mensagem de renovação forçada."
#: src/network/org.freedesktop.network1.policy:154
msgid "Renew dynamic addresses"
msgstr "Renovar endereços dinâmicos"
#: src/network/org.freedesktop.network1.policy:155
msgid "Authentication is required to renew dynamic addresses."
msgstr "É necessária autenticação para renovar endereços dinâmicos."
#: src/network/org.freedesktop.network1.policy:165
msgid "Reload network settings"
msgstr "Recarregar configurações de rede"
#: src/network/org.freedesktop.network1.policy:166
msgid "Authentication is required to reload network settings."
msgstr "É necessária autenticação para recarregar as configurações de rede."
#: src/network/org.freedesktop.network1.policy:176
msgid "Reconfigure network interface"
msgstr "Reconfigurar interface de rede"
#: src/network/org.freedesktop.network1.policy:177
msgid "Authentication is required to reconfigure network interface."
msgstr "É necessária autenticação para reconfigurar a interface de rede."
#: src/portable/org.freedesktop.portable1.policy:13 #: src/portable/org.freedesktop.portable1.policy:13
msgid "Inspect a portable service image" msgid "Inspect a portable service image"
@ -764,9 +856,9 @@ msgid "Revert name resolution settings"
msgstr "Reverter configurações de resolução de nome" msgstr "Reverter configurações de resolução de nome"
#: src/resolve/org.freedesktop.resolve1.policy:133 #: src/resolve/org.freedesktop.resolve1.policy:133
msgid "Authentication is required to revert name resolution settings." msgid "Authentication is required to reset name resolution settings."
msgstr "" msgstr ""
"É necessária autenticação para reverter as configurações de resolução de " "É necessária autenticação para redefinir as configurações de resolução de "
"nome." "nome."
#: src/timedate/org.freedesktop.timedate1.policy:22 #: src/timedate/org.freedesktop.timedate1.policy:22
@ -787,7 +879,7 @@ msgstr "É necessária autenticação para definir o fuso horário do sistema."
#: src/timedate/org.freedesktop.timedate1.policy:43 #: src/timedate/org.freedesktop.timedate1.policy:43
msgid "Set RTC to local timezone or UTC" msgid "Set RTC to local timezone or UTC"
msgstr "Definir o relógio do sistema (RTC) para fuso horário local ou UTC" msgstr "Definir RTC para fuso horário local ou UTC"
#: src/timedate/org.freedesktop.timedate1.policy:44 #: src/timedate/org.freedesktop.timedate1.policy:44
msgid "" msgid ""
@ -809,23 +901,23 @@ msgstr ""
"É necessária autenticação para controlar se deve ser habilitada, ou não, a " "É necessária autenticação para controlar se deve ser habilitada, ou não, a "
"sincronização de horário através de rede." "sincronização de horário através de rede."
#: src/core/dbus-unit.c:354 #: src/core/dbus-unit.c:358
msgid "Authentication is required to start '$(unit)'." msgid "Authentication is required to start '$(unit)'."
msgstr "É necessária autenticação para iniciar “$(unit)”." msgstr "É necessária autenticação para iniciar “$(unit)”."
#: src/core/dbus-unit.c:355 #: src/core/dbus-unit.c:359
msgid "Authentication is required to stop '$(unit)'." msgid "Authentication is required to stop '$(unit)'."
msgstr "É necessária autenticação para parar “$(unit)”." msgstr "É necessária autenticação para parar “$(unit)”."
#: src/core/dbus-unit.c:356 #: src/core/dbus-unit.c:360
msgid "Authentication is required to reload '$(unit)'." msgid "Authentication is required to reload '$(unit)'."
msgstr "É necessária autenticação para recarregar “$(unit)”." msgstr "É necessária autenticação para recarregar “$(unit)”."
#: src/core/dbus-unit.c:357 src/core/dbus-unit.c:358 #: src/core/dbus-unit.c:361 src/core/dbus-unit.c:362
msgid "Authentication is required to restart '$(unit)'." msgid "Authentication is required to restart '$(unit)'."
msgstr "É necessária autenticação para reiniciar “$(unit)”." msgstr "É necessária autenticação para reiniciar “$(unit)”."
#: src/core/dbus-unit.c:530 #: src/core/dbus-unit.c:534
msgid "" msgid ""
"Authentication is required to send a UNIX signal to the processes of " "Authentication is required to send a UNIX signal to the processes of "
"'$(unit)'." "'$(unit)'."
@ -833,16 +925,16 @@ msgstr ""
"É necessária autenticação para enviar um sinal UNIX para os processos de " "É necessária autenticação para enviar um sinal UNIX para os processos de "
"“$(unit)”." "“$(unit)”."
#: src/core/dbus-unit.c:561 #: src/core/dbus-unit.c:565
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'." msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr "" msgstr ""
"É necessária autenticação para reiniciar o estado “failed” de “$(unit)”." "É necessária autenticação para reiniciar o estado “failed” de “$(unit)”."
#: src/core/dbus-unit.c:594 #: src/core/dbus-unit.c:598
msgid "Authentication is required to set properties on '$(unit)'." msgid "Authentication is required to set properties on '$(unit)'."
msgstr "É necessária autenticação para definir propriedades em “$(unit)”." msgstr "É necessária autenticação para definir propriedades em “$(unit)”."
#: src/core/dbus-unit.c:703 #: src/core/dbus-unit.c:707
msgid "" msgid ""
"Authentication is required to delete files and directories associated with " "Authentication is required to delete files and directories associated with "
"'$(unit)'." "'$(unit)'."
@ -850,5 +942,9 @@ msgstr ""
"É necessária autenticação para excluir arquivos e diretórios associados com " "É necessária autenticação para excluir arquivos e diretórios associados com "
"“$(unit)”." "“$(unit)”."
#~ msgid "Authentication is required to kill '$(unit)'." #: src/core/dbus-unit.c:756
#~ msgstr "É necessária autenticação para matar “$(unit)”." msgid ""
"Authentication is required to freeze or thaw the processes of '$(unit)' unit."
msgstr ""
"É necessária autenticação para congelar ou descongelar os processos da "
"unidade “$(unit)”."

View File

@ -69,19 +69,21 @@ int efi_get_variable(
return 0; return 0;
} }
if (DEBUG_LOGGING) if (DEBUG_LOGGING) {
log_debug("Reading EFI variable %s.", p);
begin = now(CLOCK_MONOTONIC); begin = now(CLOCK_MONOTONIC);
}
fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC); fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC);
if (fd < 0) if (fd < 0)
return log_debug_errno(errno, "open(\"%s\") failed: %m", p); return log_debug_errno(errno, "open(\"%s\") failed: %m", p);
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return -errno; return log_debug_errno(errno, "fstat(\"%s\") failed: %m", p);
if (st.st_size < 4) if (st.st_size < 4)
return -ENODATA; return log_debug_errno(SYNTHETIC_ERRNO(ENODATA), "EFI variable %s is shorter than 4 bytes, refusing.", p);
if (st.st_size > 4*1024*1024 + 4) if (st.st_size > 4*1024*1024 + 4)
return -E2BIG; return log_debug_errno(SYNTHETIC_ERRNO(E2BIG), "EFI variable %s is ridiculously large, refusing.", p);
if (ret_value || ret_attribute) { if (ret_value || ret_attribute) {
/* The kernel ratelimits reads from the efivarfs because EFI is inefficient, and we'll /* The kernel ratelimits reads from the efivarfs because EFI is inefficient, and we'll
@ -96,31 +98,34 @@ int efi_get_variable(
n = read(fd, &a, sizeof(a)); n = read(fd, &a, sizeof(a));
if (n >= 0) if (n >= 0)
break; break;
log_debug_errno(errno, "read from \"%s\" failed: %m", p); log_debug_errno(errno, "Reading from \"%s\" failed: %m", p);
if (errno != EINTR) if (errno != EINTR)
return -errno; return -errno;
if (try >= EFI_N_RETRIES) if (try >= EFI_N_RETRIES)
return -EBUSY; return -EBUSY;
usleep(EFI_RETRY_DELAY);
(void) usleep(EFI_RETRY_DELAY);
} }
if (n != sizeof(a)) if (n != sizeof(a))
return -EIO; return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Read %zi bytes from EFI variable %s, expected %zu.", n, p, sizeof(a));
} }
if (ret_value) { if (ret_value) {
buf = malloc(st.st_size - 4 + 2); buf = malloc(st.st_size - 4 + 3);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
n = read(fd, buf, (size_t) st.st_size - 4); n = read(fd, buf, (size_t) st.st_size - 4);
if (n < 0) if (n < 0)
return -errno; return log_debug_errno(errno, "Failed to read value of EFI variable %s: %m", p);
assert(n <= st.st_size - 4); assert(n <= st.st_size - 4);
/* Always NUL terminate (2 bytes, to protect UTF-16) */ /* Always NUL terminate (3 bytes, to properly protect UTF-16, even if truncated in the middle of a character) */
((char*) buf)[n] = 0; ((char*) buf)[n] = 0;
((char*) buf)[n + 1] = 0; ((char*) buf)[n + 1] = 0;
((char*) buf)[n + 2] = 0;
} else } else
/* Assume that the reported size is accurate */ /* Assume that the reported size is accurate */
n = st.st_size - 4; n = st.st_size - 4;
@ -229,6 +234,14 @@ int efi_set_variable(
if (r < 0) if (r < 0)
goto finish; goto finish;
/* For some reason efivarfs doesn't update mtime automatically. Let's do it manually then. This is
* useful for processes that cache EFI variables to detect when changes occurred. */
if (futimens(fd, (struct timespec[2]) {
{ .tv_nsec = UTIME_NOW },
{ .tv_nsec = UTIME_NOW }
}) < 0)
log_debug_errno(errno, "Failed to update mtime/atime on %s, ignoring: %m", p);
r = 0; r = 0;
finish: finish:

View File

@ -365,6 +365,7 @@ const char *special_glyph(SpecialGlyph code) {
[SPECIAL_GLYPH_SIGMA] = "S", [SPECIAL_GLYPH_SIGMA] = "S",
[SPECIAL_GLYPH_ARROW] = "->", [SPECIAL_GLYPH_ARROW] = "->",
[SPECIAL_GLYPH_ELLIPSIS] = "...", [SPECIAL_GLYPH_ELLIPSIS] = "...",
[SPECIAL_GLYPH_EXTERNAL_LINK] = "[LNK]",
[SPECIAL_GLYPH_ECSTATIC_SMILEY] = ":-]", [SPECIAL_GLYPH_ECSTATIC_SMILEY] = ":-]",
[SPECIAL_GLYPH_HAPPY_SMILEY] = ":-}", [SPECIAL_GLYPH_HAPPY_SMILEY] = ":-}",
[SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY] = ":-)", [SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY] = ":-)",
@ -400,6 +401,9 @@ const char *special_glyph(SpecialGlyph code) {
/* Single glyph in Unicode, three in ASCII */ /* Single glyph in Unicode, three in ASCII */
[SPECIAL_GLYPH_ELLIPSIS] = "\342\200\246", /* … (actually called: HORIZONTAL ELLIPSIS) */ [SPECIAL_GLYPH_ELLIPSIS] = "\342\200\246", /* … (actually called: HORIZONTAL ELLIPSIS) */
/* Three glyphs in Unicode, five in ASCII */
[SPECIAL_GLYPH_EXTERNAL_LINK] = "[\360\237\241\225]", /* 🡕 (actually called: NORTH EAST SANS-SERIF ARROW, enclosed in []) */
/* These smileys are a single glyph in Unicode, and three in ASCII */ /* These smileys are a single glyph in Unicode, and three in ASCII */
[SPECIAL_GLYPH_ECSTATIC_SMILEY] = "\360\237\230\207", /* 😇 (actually called: SMILING FACE WITH HALO) */ [SPECIAL_GLYPH_ECSTATIC_SMILEY] = "\360\237\230\207", /* 😇 (actually called: SMILING FACE WITH HALO) */
[SPECIAL_GLYPH_HAPPY_SMILEY] = "\360\237\230\200", /* 😀 (actually called: GRINNING FACE) */ [SPECIAL_GLYPH_HAPPY_SMILEY] = "\360\237\230\200", /* 😀 (actually called: GRINNING FACE) */

View File

@ -55,6 +55,7 @@ typedef enum {
SPECIAL_GLYPH_LIGHT_SHADE, SPECIAL_GLYPH_LIGHT_SHADE,
SPECIAL_GLYPH_DARK_SHADE, SPECIAL_GLYPH_DARK_SHADE,
SPECIAL_GLYPH_SIGMA, SPECIAL_GLYPH_SIGMA,
SPECIAL_GLYPH_EXTERNAL_LINK,
_SPECIAL_GLYPH_FIRST_EMOJI, _SPECIAL_GLYPH_FIRST_EMOJI,
SPECIAL_GLYPH_ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_EMOJI, SPECIAL_GLYPH_ECSTATIC_SMILEY = _SPECIAL_GLYPH_FIRST_EMOJI,
SPECIAL_GLYPH_HAPPY_SMILEY, SPECIAL_GLYPH_HAPPY_SMILEY,

View File

@ -1041,7 +1041,10 @@ static int help(int argc, char *argv[], void *userdata) {
" remove Remove systemd-boot from the ESP and EFI variables\n" " remove Remove systemd-boot from the ESP and EFI variables\n"
" is-installed Test whether systemd-boot is installed in the ESP\n" " is-installed Test whether systemd-boot is installed in the ESP\n"
" random-seed Initialize random seed in ESP and EFI variables\n" " random-seed Initialize random seed in ESP and EFI variables\n"
" systemd-efi-options Query or set system options string in EFI variable\n" " systemd-efi-options [STRING]\n"
" Query or set system options string in EFI variable\n"
" reboot-to-firmware [BOOL]\n"
" Query or set reboot-to-firmware EFI flag\n"
"\nBoot Loader Entries Commands:\n" "\nBoot Loader Entries Commands:\n"
" list List boot loader entries\n" " list List boot loader entries\n"
" set-default ID Set default boot loader entry\n" " set-default ID Set default boot loader entry\n"
@ -1245,6 +1248,18 @@ static int verb_status(int argc, char *argv[], void *userdata) {
printf(" Firmware: %s%s (%s)%s\n", ansi_highlight(), strna(fw_type), strna(fw_info), ansi_normal()); printf(" Firmware: %s%s (%s)%s\n", ansi_highlight(), strna(fw_type), strna(fw_info), ansi_normal());
printf(" Secure Boot: %sd\n", enable_disable(is_efi_secure_boot())); printf(" Secure Boot: %sd\n", enable_disable(is_efi_secure_boot()));
printf(" Setup Mode: %s\n", is_efi_secure_boot_setup_mode() ? "setup" : "user"); printf(" Setup Mode: %s\n", is_efi_secure_boot_setup_mode() ? "setup" : "user");
r = efi_get_reboot_to_firmware();
if (r > 0)
printf(" Boot into FW: %sactive%s\n", ansi_highlight_yellow(), ansi_normal());
else if (r == 0)
printf(" Boot into FW: supported\n");
else if (r == -EOPNOTSUPP)
printf(" Boot into FW: not supported\n");
else {
errno = -r;
printf(" Boot into FW: %sfailed%s (%m)\n", ansi_highlight_red(), ansi_normal());
}
printf("\n"); printf("\n");
printf("Current Boot Loader:\n"); printf("Current Boot Loader:\n");
@ -1311,6 +1326,7 @@ static int verb_status(int argc, char *argv[], void *userdata) {
static int verb_list(int argc, char *argv[], void *userdata) { static int verb_list(int argc, char *argv[], void *userdata) {
_cleanup_(boot_config_free) BootConfig config = {}; _cleanup_(boot_config_free) BootConfig config = {};
_cleanup_strv_free_ char **efi_entries = NULL;
int r; int r;
/* If we lack privileges we invoke find_esp_and_warn() in "unprivileged mode" here, which does two things: turn /* If we lack privileges we invoke find_esp_and_warn() in "unprivileged mode" here, which does two things: turn
@ -1333,7 +1349,13 @@ static int verb_list(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
(void) boot_entries_augment_from_loader(&config, false); r = efi_loader_get_entries(&efi_entries);
if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r))
log_debug_errno(r, "Boot loader reported no entries.");
else if (r < 0)
log_warning_errno(r, "Failed to determine entries reported by boot loader, ignoring: %m");
else
(void) boot_entries_augment_from_loader(&config, efi_entries, false);
if (config.n_entries == 0) if (config.n_entries == 0)
log_info("No boot loader entries found."); log_info("No boot loader entries found.");
@ -1766,6 +1788,39 @@ static int verb_systemd_efi_options(int argc, char *argv[], void *userdata) {
return 0; return 0;
} }
static int verb_reboot_to_firmware(int argc, char *argv[], void *userdata) {
int r;
if (argc < 2) {
r = efi_get_reboot_to_firmware();
if (r > 0) {
puts("active");
return EXIT_SUCCESS; /* success */
}
if (r == 0) {
puts("supported");
return 1; /* recognizable error #1 */
}
if (r == -EOPNOTSUPP) {
puts("not supported");
return 2; /* recognizable error #2 */
}
log_error_errno(r, "Failed to query reboot-to-firmware state: %m");
return 3; /* other kind of error */
} else {
r = parse_boolean(argv[1]);
if (r < 0)
return log_error_errno(r, "Failed to parse argument: %s", argv[1]);
r = efi_set_reboot_to_firmware(r);
if (r < 0)
return log_error_errno(r, "Failed to set reboot-to-firmware option: %m");
return 0;
}
}
static int bootctl_main(int argc, char *argv[]) { static int bootctl_main(int argc, char *argv[]) {
static const Verb verbs[] = { static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help }, { "help", VERB_ANY, VERB_ANY, 0, help },
@ -1779,6 +1834,7 @@ static int bootctl_main(int argc, char *argv[]) {
{ "set-oneshot", 2, 2, 0, verb_set_default }, { "set-oneshot", 2, 2, 0, verb_set_default },
{ "random-seed", VERB_ANY, 1, 0, verb_random_seed }, { "random-seed", VERB_ANY, 1, 0, verb_random_seed },
{ "systemd-efi-options", VERB_ANY, 2, 0, verb_systemd_efi_options }, { "systemd-efi-options", VERB_ANY, 2, 0, verb_systemd_efi_options },
{ "reboot-to-firmware", VERB_ANY, 2, 0, verb_reboot_to_firmware },
{} {}
}; };
@ -1802,4 +1858,4 @@ static int run(int argc, char *argv[]) {
return bootctl_main(argc, argv); return bootctl_main(argc, argv);
} }
DEFINE_MAIN_FUNCTION(run); DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run);

View File

@ -50,6 +50,7 @@
#include "io-util.h" #include "io-util.h"
#include "label.h" #include "label.h"
#include "locale-setup.h" #include "locale-setup.h"
#include "load-fragment.h"
#include "log.h" #include "log.h"
#include "macro.h" #include "macro.h"
#include "manager.h" #include "manager.h"
@ -1929,6 +1930,12 @@ unsigned manager_dispatch_load_queue(Manager *m) {
return n; return n;
} }
static bool manager_unit_cache_needs_refresh(Manager *m) {
assert(m);
return m->unit_cache_mtime > 0 && !lookup_paths_mtime_good(&m->lookup_paths, m->unit_cache_mtime);
}
int manager_load_unit_prepare( int manager_load_unit_prepare(
Manager *m, Manager *m,
const char *name, const char *name,
@ -1969,18 +1976,27 @@ int manager_load_unit_prepare(
ret = manager_get_unit(m, name); ret = manager_get_unit(m, name);
if (ret) { if (ret) {
/* The time-based cache allows to start new units without daemon-reload,
* but if they are already referenced (because of dependencies or ordering)
* then we have to force a load of the fragment. As an optimization, check
* first if anything in the usual paths was modified since the last time
* the cache was loaded. */
if (ret->load_state == UNIT_NOT_FOUND && manager_unit_cache_needs_refresh(m))
ret->load_state = UNIT_STUB;
else {
*_ret = ret; *_ret = ret;
return 1; return 1;
} }
} else {
ret = cleanup_ret = unit_new(m, unit_vtable[t]->object_size); ret = cleanup_ret = unit_new(m, unit_vtable[t]->object_size);
if (!ret) if (!ret)
return -ENOMEM; return -ENOMEM;
}
if (path) { if (path) {
ret->fragment_path = strdup(path); r = free_and_strdup(&ret->fragment_path, path);
if (!ret->fragment_path) if (r < 0)
return -ENOMEM; return r;
} }
r = unit_add_name(ret, name); r = unit_add_name(ret, name);

View File

@ -7,7 +7,6 @@
#include <linux/if_packet.h> #include <linux/if_packet.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <net/if_arp.h>
#include <stdint.h> #include <stdint.h>
#include "sd-dhcp-client.h" #include "sd-dhcp-client.h"
@ -23,6 +22,11 @@ typedef struct sd_dhcp_option {
size_t length; size_t length;
} sd_dhcp_option; } sd_dhcp_option;
typedef struct DHCPServerData {
struct in_addr *addr;
size_t size;
} DHCPServerData;
extern const struct hash_ops dhcp_option_hash_ops; extern const struct hash_ops dhcp_option_hash_ops;
int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link,

View File

@ -5,11 +5,9 @@
Copyright © 2013 Intel Corporation. All rights reserved. Copyright © 2013 Intel Corporation. All rights reserved.
***/ ***/
#include <stdint.h>
#include <linux/if_packet.h>
#include "sd-dhcp-client.h" #include "sd-dhcp-client.h"
#include "dhcp-internal.h"
#include "dhcp-protocol.h" #include "dhcp-protocol.h"
#include "list.h" #include "list.h"
#include "util.h" #include "util.h"
@ -52,23 +50,7 @@ struct sd_dhcp_lease {
struct in_addr *router; struct in_addr *router;
size_t router_size; size_t router_size;
struct in_addr *dns; DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
size_t dns_size;
struct in_addr *ntp;
size_t ntp_size;
struct in_addr *sip;
size_t sip_size;
struct in_addr *pop3_server;
size_t pop3_server_size;
struct in_addr *smtp_server;
size_t smtp_server_size;
struct in_addr *lpr_server;
size_t lpr_server_size;
struct sd_dhcp_route *static_route; struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated; size_t static_route_size, static_route_allocated;

View File

@ -56,8 +56,7 @@ struct sd_dhcp_server {
char *timezone; char *timezone;
struct in_addr *ntp, *dns, *sip, *pop3_server, *smtp_server, *lpr_server; DHCPServerData servers[_SD_DHCP_LEASE_SERVER_TYPE_MAX];
size_t n_ntp, n_dns, n_sip, n_pop3_server, n_smtp_server, n_lpr_server;
OrderedHashmap *extra_options; OrderedHashmap *extra_options;
OrderedHashmap *vendor_options; OrderedHashmap *vendor_options;

View File

@ -98,78 +98,38 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
int sd_dhcp_lease_get_servers( int sd_dhcp_lease_get_servers(
sd_dhcp_lease *lease, sd_dhcp_lease *lease,
sd_dhcp_lease_info what, sd_dhcp_lease_server_type what,
const struct in_addr **addr) { const struct in_addr **addr) {
assert_return(lease, -EINVAL); assert_return(lease, -EINVAL);
assert_return(what >= 0, -EINVAL);
assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL);
assert_return(addr, -EINVAL); assert_return(addr, -EINVAL);
switch (what) { if (lease->servers[what].size <= 0)
case SD_DHCP_LEASE_DNS_SERVERS:
if (lease->dns_size <= 0)
return -ENODATA; return -ENODATA;
*addr = lease->dns; *addr = lease->servers[what].addr;
return (int) lease->dns_size; return (int) lease->servers[what].size;
case SD_DHCP_LEASE_NTP_SERVERS:
if (lease->ntp_size <= 0)
return -ENODATA;
*addr = lease->ntp;
return (int) lease->ntp_size;
case SD_DHCP_LEASE_SIP_SERVERS:
if (lease->sip_size <= 0)
return -ENODATA;
*addr = lease->sip;
return (int) lease->sip_size;
case SD_DHCP_LEASE_POP3_SERVERS:
if (lease->pop3_server_size <= 0)
return -ENODATA;
*addr = lease->pop3_server;
return (int) lease->pop3_server_size;
case SD_DHCP_LEASE_SMTP_SERVERS:
if (lease->smtp_server_size <= 0)
return -ENODATA;
*addr = lease->smtp_server;
return (int) lease->smtp_server_size;
case SD_DHCP_LEASE_LPR_SERVERS:
if (lease->lpr_server_size <= 0)
return -ENODATA;
*addr = lease->lpr_server;
return (int) lease->lpr_server_size;
default:
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO),
"Unknown DHCP lease info item %d.", what);
}
} }
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_DNS_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_DNS, addr);
} }
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_NTP_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_NTP, addr);
} }
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP, addr);
} }
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3, addr);
} }
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP, addr);
} }
int sd_dhcp_lease_get_lpr_servers(sd_dhcp_lease *lease, const struct in_addr **addr) { int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_LPR_SERVERS, addr); return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_LPR, addr);
} }
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
@ -319,12 +279,10 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->timezone); free(lease->timezone);
free(lease->hostname); free(lease->hostname);
free(lease->domainname); free(lease->domainname);
free(lease->dns);
free(lease->ntp); for (sd_dhcp_lease_server_type i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
free(lease->sip); free(lease->servers[i].addr);
free(lease->pop3_server);
free(lease->smtp_server);
free(lease->lpr_server);
free(lease->static_route); free(lease->static_route);
free(lease->client_id); free(lease->client_id);
free(lease->vendor_specific); free(lease->vendor_specific);
@ -430,7 +388,7 @@ static int lease_parse_domain(const uint8_t *option, size_t len, char **ret) {
} }
static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) { static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option); assert(option || len == 0);
assert(ret); assert(ret);
assert(n_ret); assert(n_ret);
@ -459,33 +417,24 @@ static int lease_parse_in_addrs(const uint8_t *option, size_t len, struct in_add
} }
static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) { static int lease_parse_sip_server(const uint8_t *option, size_t len, struct in_addr **ret, size_t *n_ret) {
assert(option); assert(option || len == 0);
assert(ret); assert(ret);
assert(n_ret); assert(n_ret);
if (len <= 0) { if (len <= 0)
*ret = mfree(*ret);
*n_ret = 0;
} else {
size_t n_addresses;
struct in_addr *addresses;
int l = len - 1;
if (l % 4 != 0)
return -EINVAL; return -EINVAL;
n_addresses = l / 4; /* The SIP record is like the other, regular server records, but prefixed with a single "encoding"
* byte that is either 0 or 1. We only support it to be 1 for now. Let's drop it and parse it like
* the other fields */
addresses = newdup(struct in_addr, option + 1, n_addresses); if (option[0] != 1) { /* We only support IP address encoding for now */
if (!addresses) *ret = mfree(*ret);
return -ENOMEM; *n_ret = 0;
return 0;
free(*ret);
*ret = addresses;
*n_ret = n_addresses;
} }
return 0; return lease_parse_in_addrs(option + 1, len - 1, ret, n_ret);
} }
static int lease_parse_routes( static int lease_parse_routes(
@ -630,37 +579,37 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
break; break;
case SD_DHCP_OPTION_DOMAIN_NAME_SERVER: case SD_DHCP_OPTION_DOMAIN_NAME_SERVER:
r = lease_parse_in_addrs(option, len, &lease->dns, &lease->dns_size); r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_DNS].addr, &lease->servers[SD_DHCP_LEASE_DNS].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse DNS server, ignoring: %m"); log_debug_errno(r, "Failed to parse DNS server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_NTP_SERVER: case SD_DHCP_OPTION_NTP_SERVER:
r = lease_parse_in_addrs(option, len, &lease->ntp, &lease->ntp_size); r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_NTP].addr, &lease->servers[SD_DHCP_LEASE_NTP].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse NTP server, ignoring: %m"); log_debug_errno(r, "Failed to parse NTP server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_SIP_SERVER: case SD_DHCP_OPTION_SIP_SERVER:
r = lease_parse_sip_server(option, len, &lease->sip, &lease->sip_size); r = lease_parse_sip_server(option, len, &lease->servers[SD_DHCP_LEASE_SIP].addr, &lease->servers[SD_DHCP_LEASE_SIP].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m"); log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_POP3_SERVER: case SD_DHCP_OPTION_POP3_SERVER:
r = lease_parse_in_addrs(option, len, &lease->pop3_server, &lease->pop3_server_size); r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_POP3].addr, &lease->servers[SD_DHCP_LEASE_POP3].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m"); log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_SMTP_SERVER: case SD_DHCP_OPTION_SMTP_SERVER:
r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size); r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_SMTP].addr, &lease->servers[SD_DHCP_LEASE_SMTP].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m"); log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_LPR_SERVER: case SD_DHCP_OPTION_LPR_SERVER:
r = lease_parse_in_addrs(option, len, &lease->lpr_server, &lease->lpr_server_size); r = lease_parse_in_addrs(option, len, &lease->servers[SD_DHCP_LEASE_LPR].addr, &lease->servers[SD_DHCP_LEASE_LPR].size);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to parse LPR server, ignoring: %m"); log_debug_errno(r, "Failed to parse LPR server, ignoring: %m");
break; break;
@ -1101,9 +1050,9 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*dns = NULL, *dns = NULL,
*ntp = NULL, *ntp = NULL,
*sip = NULL, *sip = NULL,
*pop3_server = NULL, *pop3 = NULL,
*smtp_server = NULL, *smtp = NULL,
*lpr_server = NULL, *lpr = NULL,
*mtu = NULL, *mtu = NULL,
*routes = NULL, *routes = NULL,
*domains = NULL, *domains = NULL,
@ -1133,9 +1082,9 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"DNS", &dns, "DNS", &dns,
"NTP", &ntp, "NTP", &ntp,
"SIP", &sip, "SIP", &sip,
"POP3_SERVERS", &pop3_server, "POP3", &pop3,
"SMTP_SERVERS", &smtp_server, "SMTP", &smtp,
"LPR_SERVERS", &lpr_server, "LPR", &lpr,
"MTU", &mtu, "MTU", &mtu,
"DOMAINNAME", &lease->domainname, "DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname, "HOSTNAME", &lease->hostname,
@ -1225,54 +1174,53 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
} }
if (dns) { if (dns) {
r = deserialize_in_addrs(&lease->dns, dns); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_DNS].addr, dns);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns); log_debug_errno(r, "Failed to deserialize DNS servers %s, ignoring: %m", dns);
else else
lease->dns_size = r; lease->servers[SD_DHCP_LEASE_DNS].size = r;
} }
if (ntp) { if (ntp) {
r = deserialize_in_addrs(&lease->ntp, ntp); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_NTP].addr, ntp);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp); log_debug_errno(r, "Failed to deserialize NTP servers %s, ignoring: %m", ntp);
else else
lease->ntp_size = r; lease->servers[SD_DHCP_LEASE_NTP].size = r;
} }
if (sip) { if (sip) {
r = deserialize_in_addrs(&lease->sip, sip); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SIP].addr, sip);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip); log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
else else
lease->sip_size = r; lease->servers[SD_DHCP_LEASE_SIP].size = r;
} }
if (pop3_server) { if (pop3) {
r = deserialize_in_addrs(&lease->pop3_server, pop3_server); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_POP3].addr, pop3);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3_server); log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3);
else else
lease->pop3_server_size = r; lease->servers[SD_DHCP_LEASE_POP3].size = r;
} }
if (smtp_server) { if (smtp) {
r = deserialize_in_addrs(&lease->smtp_server, smtp_server); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_SMTP].addr, smtp);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server); log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp);
else else
lease->smtp_server_size = r; lease->servers[SD_DHCP_LEASE_SMTP].size = r;
} }
if (lpr_server) { if (lpr) {
r = deserialize_in_addrs(&lease->lpr_server, lpr_server); r = deserialize_in_addrs(&lease->servers[SD_DHCP_LEASE_LPR].addr, lpr);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to deserialize LPR server %s, ignoring: %m", lpr_server); log_debug_errno(r, "Failed to deserialize LPR server %s, ignoring: %m", lpr);
else else
lease->lpr_server_size = r; lease->servers[SD_DHCP_LEASE_LPR].size = r;
} }
if (mtu) { if (mtu) {
r = safe_atou16(mtu, &lease->mtu); r = safe_atou16(mtu, &lease->mtu);
if (r < 0) if (r < 0)

View File

@ -3,6 +3,7 @@
Copyright © 2013 Intel Corporation. All rights reserved. Copyright © 2013 Intel Corporation. All rights reserved.
***/ ***/
#include <net/if_arp.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "sd-dhcp-server.h" #include "sd-dhcp-server.h"
@ -143,12 +144,9 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
sd_event_unref(server->event); sd_event_unref(server->event);
free(server->timezone); free(server->timezone);
free(server->dns);
free(server->ntp); for (sd_dhcp_lease_server_type i = 0; i < _SD_DHCP_LEASE_SERVER_TYPE_MAX; i++)
free(server->sip); free(server->servers[i].addr);
free(server->pop3_server);
free(server->smtp_server);
free(server->lpr_server);
hashmap_free(server->leases_by_client_id); hashmap_free(server->leases_by_client_id);
@ -461,8 +459,20 @@ static int server_send_offer(sd_dhcp_server *server, DHCPRequest *req,
return 0; return 0;
} }
static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req, static int server_send_ack(
sd_dhcp_server *server,
DHCPRequest *req,
be32_t address) { be32_t address) {
static const uint8_t option_map[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
[SD_DHCP_LEASE_DNS] = SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
[SD_DHCP_LEASE_NTP] = SD_DHCP_OPTION_NTP_SERVER,
[SD_DHCP_LEASE_SIP] = SD_DHCP_OPTION_SIP_SERVER,
[SD_DHCP_LEASE_POP3] = SD_DHCP_OPTION_POP3_SERVER,
[SD_DHCP_LEASE_SMTP] = SD_DHCP_OPTION_SMTP_SERVER,
[SD_DHCP_LEASE_LPR] = SD_DHCP_OPTION_LPR_SERVER,
};
_cleanup_free_ DHCPPacket *packet = NULL; _cleanup_free_ DHCPPacket *packet = NULL;
be32_t lease_time; be32_t lease_time;
sd_dhcp_option *j; sd_dhcp_option *j;
@ -495,59 +505,19 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
return r; return r;
} }
if (server->n_dns > 0) { for (sd_dhcp_lease_server_type k = 0; k < _SD_DHCP_LEASE_SERVER_TYPE_MAX; k++) {
if (server->servers[k].size <= 0)
continue;
r = dhcp_option_append( r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0, &packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_DOMAIN_NAME_SERVER, option_map[k],
sizeof(struct in_addr) * server->n_dns, server->dns); sizeof(struct in_addr) * server->servers[k].size, server->servers[k].addr);
if (r < 0) if (r < 0)
return r; return r;
} }
if (server->n_ntp > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_NTP_SERVER,
sizeof(struct in_addr) * server->n_ntp, server->ntp);
if (r < 0)
return r;
}
if (server->n_sip > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_SIP_SERVER,
sizeof(struct in_addr) * server->n_sip, server->sip);
if (r < 0)
return r;
}
if (server->n_pop3_server > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_POP3_SERVER,
sizeof(struct in_addr) * server->n_pop3_server, server->pop3_server);
if (r < 0)
return r;
}
if (server->n_smtp_server > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_SMTP_SERVER,
sizeof(struct in_addr) * server->n_smtp_server, server->smtp_server);
if (r < 0)
return r;
}
if (server->n_lpr_server > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_LPR_SERVER,
sizeof(struct in_addr) * server->n_lpr_server, server->lpr_server);
if (r < 0)
return r;
}
if (server->timezone) { if (server->timezone) {
r = dhcp_option_append( r = dhcp_option_append(
@ -1139,87 +1109,50 @@ int sd_dhcp_server_set_default_lease_time(sd_dhcp_server *server, uint32_t t) {
int sd_dhcp_server_set_servers( int sd_dhcp_server_set_servers(
sd_dhcp_server *server, sd_dhcp_server *server,
sd_dhcp_lease_info what, sd_dhcp_lease_server_type what,
const struct in_addr addresses[], const struct in_addr addresses[],
size_t n_addresses) { size_t n_addresses) {
struct in_addr *c = NULL;
assert_return(server, -EINVAL); assert_return(server, -EINVAL);
assert_return(addresses || n_addresses == 0, -EINVAL); assert_return(addresses || n_addresses == 0, -EINVAL);
assert_return(what >= 0, -EINVAL);
assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL);
struct in_addr **a; if (server->servers[what].size == n_addresses &&
size_t *n_a; memcmp(server->servers[what].addr, addresses, sizeof(struct in_addr) * n_addresses) == 0)
switch (what) {
case SD_DHCP_LEASE_DNS_SERVERS:
a = &server->dns;
n_a = &server->n_dns;
break;
case SD_DHCP_LEASE_NTP_SERVERS:
a = &server->ntp;
n_a = &server->n_ntp;
break;
case SD_DHCP_LEASE_SIP_SERVERS:
a = &server->sip;
n_a = &server->n_sip;
break;
case SD_DHCP_LEASE_POP3_SERVERS:
a = &server->pop3_server;
n_a = &server->n_pop3_server;
break;
case SD_DHCP_LEASE_SMTP_SERVERS:
a = &server->smtp_server;
n_a = &server->n_smtp_server;
break;
case SD_DHCP_LEASE_LPR_SERVERS:
a = &server->lpr_server;
n_a = &server->n_lpr_server;
break;
default:
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO),
"Unknown DHCP lease info item %d.", what);
}
if (*n_a == n_addresses &&
memcmp(*a, addresses, sizeof(struct in_addr) * n_addresses) == 0)
return 0; return 0;
struct in_addr *c = NULL;
if (n_addresses > 0) { if (n_addresses > 0) {
c = newdup(struct in_addr, addresses, n_addresses); c = newdup(struct in_addr, addresses, n_addresses);
if (!c) if (!c)
return -ENOMEM; return -ENOMEM;
} }
free(*a); free(server->servers[what].addr);
*a = c; server->servers[what].addr = c;
*n_a = n_addresses; server->servers[what].size = n_addresses;
return 1; return 1;
} }
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], size_t n) { int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_DNS_SERVERS, dns, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_DNS, dns, n);
} }
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], size_t n) { int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_NTP_SERVERS, ntp, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_NTP, ntp, n);
} }
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], size_t n) { int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SIP_SERVERS, sip, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SIP, sip, n);
} }
int sd_dhcp_server_set_pop3(sd_dhcp_server *server, const struct in_addr pop3[], size_t n) { int sd_dhcp_server_set_pop3(sd_dhcp_server *server, const struct in_addr pop3[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_POP3_SERVERS, pop3, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_POP3, pop3, n);
} }
int sd_dhcp_server_set_smtp(sd_dhcp_server *server, const struct in_addr smtp[], size_t n) { int sd_dhcp_server_set_smtp(sd_dhcp_server *server, const struct in_addr smtp[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP_SERVERS, smtp, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP, smtp, n);
} }
int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], size_t n) { int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], size_t n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_LPR_SERVERS, lpr, n); return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_LPR, lpr, n);
} }
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) { int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {

View File

@ -4,10 +4,11 @@
***/ ***/
#include <errno.h> #include <errno.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h> #include <stdio.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <net/if.h>
#include "sd-dhcp-client.h" #include "sd-dhcp-client.h"
#include "sd-event.h" #include "sd-event.h"

View File

@ -1,4 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h> #include <errno.h>
#include <net/if_arp.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>

View File

@ -4,6 +4,7 @@
***/ ***/
#include <errno.h> #include <errno.h>
#include <net/if_arp.h>
#include "sd-dhcp-server.h" #include "sd-dhcp-server.h"
#include "sd-event.h" #include "sd-event.h"

View File

@ -16,6 +16,7 @@
#include "cgroup-util.h" #include "cgroup-util.h"
#include "conf-parser.h" #include "conf-parser.h"
#include "device-util.h" #include "device-util.h"
#include "efi-loader.h"
#include "errno-util.h" #include "errno-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "limits-util.h" #include "limits-util.h"
@ -817,3 +818,27 @@ void manager_reconnect_utmp(Manager *m) {
manager_connect_utmp(m); manager_connect_utmp(m);
#endif #endif
} }
int manager_read_efi_boot_loader_entries(Manager *m) {
#if ENABLE_EFI
int r;
assert(m);
if (m->efi_boot_loader_entries_set)
return 0;
r = efi_loader_get_entries(&m->efi_boot_loader_entries);
if (r == -ENOENT || ERRNO_IS_NOT_SUPPORTED(r)) {
log_debug_errno(r, "Boot loader reported no entries.");
m->efi_boot_loader_entries_set = true;
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to determine entries reported by boot loader: %m");
m->efi_boot_loader_entries_set = true;
return 1;
#else
return 0;
#endif
}

View File

@ -2969,17 +2969,20 @@ static int property_get_reboot_to_boot_loader_entry(
return sd_bus_message_append(reply, "s", v); return sd_bus_message_append(reply, "s", v);
} }
static int boot_loader_entry_exists(const char *id) { static int boot_loader_entry_exists(Manager *m, const char *id) {
_cleanup_(boot_config_free) BootConfig config = {}; _cleanup_(boot_config_free) BootConfig config = {};
int r; int r;
assert(m);
assert(id); assert(id);
r = boot_entries_load_config_auto(NULL, NULL, &config); r = boot_entries_load_config_auto(NULL, NULL, &config);
if (r < 0 && r != -ENOKEY) /* don't complain if no GPT is found, hence skip ENOKEY */ if (r < 0 && r != -ENOKEY) /* don't complain if no GPT is found, hence skip ENOKEY */
return r; return r;
(void) boot_entries_augment_from_loader(&config, true); r = manager_read_efi_boot_loader_entries(m);
if (r >= 0)
(void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, true);
return boot_config_has_entry(&config, id); return boot_config_has_entry(&config, id);
} }
@ -3004,7 +3007,7 @@ static int method_set_reboot_to_boot_loader_entry(
if (isempty(v)) if (isempty(v))
v = NULL; v = NULL;
else if (efi_loader_entry_name_valid(v)) { else if (efi_loader_entry_name_valid(v)) {
r = boot_loader_entry_exists(v); r = boot_loader_entry_exists(m, v);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) if (r == 0)
@ -3123,18 +3126,21 @@ static int property_get_boot_loader_entries(
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_(boot_config_free) BootConfig config = {}; _cleanup_(boot_config_free) BootConfig config = {};
Manager *m = userdata;
size_t i; size_t i;
int r; int r;
assert(bus); assert(bus);
assert(reply); assert(reply);
assert(userdata); assert(m);
r = boot_entries_load_config_auto(NULL, NULL, &config); r = boot_entries_load_config_auto(NULL, NULL, &config);
if (r < 0 && r != -ENOKEY) /* don't complain if there's no GPT found */ if (r < 0 && r != -ENOKEY) /* don't complain if there's no GPT found */
return r; return r;
(void) boot_entries_augment_from_loader(&config, true); r = manager_read_efi_boot_loader_entries(m);
if (r >= 0)
(void) boot_entries_augment_from_loader(&config, m->efi_boot_loader_entries, true);
r = sd_bus_message_open_container(reply, 'a', "s"); r = sd_bus_message_open_container(reply, 'a', "s");
if (r < 0) if (r < 0)

View File

@ -166,6 +166,8 @@ static Manager* manager_unref(Manager *m) {
free(m->wall_message); free(m->wall_message);
free(m->action_job); free(m->action_job);
strv_free(m->efi_boot_loader_entries);
return mfree(m); return mfree(m);
} }

View File

@ -123,6 +123,9 @@ struct Manager {
uint64_t runtime_dir_inodes; uint64_t runtime_dir_inodes;
uint64_t sessions_max; uint64_t sessions_max;
uint64_t inhibitors_max; uint64_t inhibitors_max;
char **efi_boot_loader_entries;
bool efi_boot_loader_entries_set;
}; };
void manager_reset_config(Manager *m); void manager_reset_config(Manager *m);
@ -168,3 +171,5 @@ CONFIG_PARSER_PROTOTYPE(config_parse_tmpfs_size);
int manager_setup_wall_message_timer(Manager *m); int manager_setup_wall_message_timer(Manager *m);
bool logind_wall_tty_filter(const char *tty, void *userdata); bool logind_wall_tty_filter(const char *tty, void *userdata);
int manager_read_efi_boot_loader_entries(Manager *m);

View File

@ -44,7 +44,7 @@ static void l2tp_session_free(L2tpSession *s) {
return; return;
if (s->tunnel && s->section) if (s->tunnel && s->section)
ordered_hashmap_remove(s->tunnel->sessions_by_section, s); ordered_hashmap_remove(s->tunnel->sessions_by_section, s->section);
network_config_section_free(s->section); network_config_section_free(s->section);

View File

@ -79,7 +79,7 @@ static int link_push_uplink_dns_to_dhcp_server(Link *link, sd_dhcp_server *s) {
static int link_push_uplink_to_dhcp_server( static int link_push_uplink_to_dhcp_server(
Link *link, Link *link,
sd_dhcp_lease_info what, sd_dhcp_lease_server_type what,
sd_dhcp_server *s) { sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL; _cleanup_free_ struct in_addr *addresses = NULL;
@ -90,35 +90,35 @@ static int link_push_uplink_to_dhcp_server(
if (!link->network) if (!link->network)
return 0; return 0;
log_link_debug(link, "Copying %s from link", dhcp_lease_info_to_string(what)); log_link_debug(link, "Copying %s from link", dhcp_lease_server_type_to_string(what));
switch (what) { switch (what) {
case SD_DHCP_LEASE_DNS_SERVERS: case SD_DHCP_LEASE_DNS:
/* DNS servers are stored as parsed data, so special handling is required. /* DNS servers are stored as parsed data, so special handling is required.
* TODO: check if DNS servers should be stored unparsed too. */ * TODO: check if DNS servers should be stored unparsed too. */
return link_push_uplink_dns_to_dhcp_server(link, s); return link_push_uplink_dns_to_dhcp_server(link, s);
case SD_DHCP_LEASE_NTP_SERVERS: case SD_DHCP_LEASE_NTP:
servers = link->network->ntp; servers = link->network->ntp;
lease_condition = link->network->dhcp_use_ntp; lease_condition = link->network->dhcp_use_ntp;
break; break;
case SD_DHCP_LEASE_POP3_SERVERS: case SD_DHCP_LEASE_POP3:
servers = link->network->pop3; servers = link->network->pop3;
lease_condition = true; lease_condition = true;
break; break;
case SD_DHCP_LEASE_SMTP_SERVERS: case SD_DHCP_LEASE_SMTP:
servers = link->network->smtp; servers = link->network->smtp;
lease_condition = true; lease_condition = true;
break; break;
case SD_DHCP_LEASE_SIP_SERVERS: case SD_DHCP_LEASE_SIP:
servers = link->network->sip; servers = link->network->sip;
lease_condition = link->network->dhcp_use_sip; lease_condition = link->network->dhcp_use_sip;
break; break;
case SD_DHCP_LEASE_LPR_SERVERS: case SD_DHCP_LEASE_LPR:
servers = link->network->lpr; servers = link->network->lpr;
lease_condition = true; lease_condition = true;
break; break;
@ -290,38 +290,38 @@ int dhcp4_server_configure(Link *link) {
const struct in_addr *servers; const struct in_addr *servers;
unsigned n_servers; unsigned n_servers;
} configs[] = { } configs[] = {
[SD_DHCP_LEASE_DNS_SERVERS] = { [SD_DHCP_LEASE_DNS] = {
link->network->dhcp_server_emit_dns, link->network->dhcp_server_emit_dns,
link->network->dhcp_server_dns, link->network->dhcp_server_dns,
link->network->n_dhcp_server_dns, link->network->n_dhcp_server_dns,
}, },
[SD_DHCP_LEASE_NTP_SERVERS] = { [SD_DHCP_LEASE_NTP] = {
link->network->dhcp_server_emit_ntp, link->network->dhcp_server_emit_ntp,
link->network->dhcp_server_ntp, link->network->dhcp_server_ntp,
link->network->n_dhcp_server_ntp, link->network->n_dhcp_server_ntp,
}, },
[SD_DHCP_LEASE_SIP_SERVERS] = { [SD_DHCP_LEASE_SIP] = {
link->network->dhcp_server_emit_sip, link->network->dhcp_server_emit_sip,
link->network->dhcp_server_sip, link->network->dhcp_server_sip,
link->network->n_dhcp_server_sip, link->network->n_dhcp_server_sip,
}, },
[SD_DHCP_LEASE_POP3_SERVERS] = { [SD_DHCP_LEASE_POP3] = {
true, true,
link->network->dhcp_server_pop3, link->network->dhcp_server_pop3,
link->network->n_dhcp_server_pop3, link->network->n_dhcp_server_pop3,
}, },
[SD_DHCP_LEASE_SMTP_SERVERS] = { [SD_DHCP_LEASE_SMTP] = {
true, true,
link->network->dhcp_server_smtp, link->network->dhcp_server_smtp,
link->network->n_dhcp_server_smtp, link->network->n_dhcp_server_smtp,
}, },
[SD_DHCP_LEASE_LPR_SERVERS] = { [SD_DHCP_LEASE_LPR] = {
true, true,
link->network->dhcp_server_lpr, link->network->dhcp_server_lpr,
link->network->n_dhcp_server_lpr, link->network->n_dhcp_server_lpr,
}, },
}; };
assert_cc(ELEMENTSOF(configs) == _SD_DHCP_LEASE_INFO_MAX); assert_cc(ELEMENTSOF(configs) == _SD_DHCP_LEASE_SERVER_TYPE_MAX);
for (unsigned n = 0; n < ELEMENTSOF(configs); n++) for (unsigned n = 0; n < ELEMENTSOF(configs); n++)
if (configs[n].condition) { if (configs[n].condition) {
@ -337,17 +337,17 @@ int dhcp4_server_configure(Link *link) {
if (!uplink) { if (!uplink) {
log_link_debug(link, log_link_debug(link,
"Not emitting %s on link, couldn't find suitable uplink.", "Not emitting %s on link, couldn't find suitable uplink.",
dhcp_lease_info_to_string(n)); dhcp_lease_server_type_to_string(n));
r = 0; r = 0;
} else if (uplink->network) } else if (uplink->network)
r = link_push_uplink_to_dhcp_server(uplink, n, link->dhcp_server); r = link_push_uplink_to_dhcp_server(uplink, n, link->dhcp_server);
else if (n == SD_DHCP_LEASE_DNS_SERVERS) else if (n == SD_DHCP_LEASE_DNS)
r = dhcp4_server_set_dns_from_resolve_conf(link); r = dhcp4_server_set_dns_from_resolve_conf(link);
} }
if (r < 0) if (r < 0)
log_link_warning_errno(link, r, log_link_warning_errno(link, r,
"Failed to set %s for DHCP server, ignoring: %m", "Failed to set %s for DHCP server, ignoring: %m",
dhcp_lease_info_to_string(n)); dhcp_lease_server_type_to_string(n));
} }
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router); r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);

View File

@ -4012,7 +4012,7 @@ static void serialize_addresses(
char **addresses, char **addresses,
sd_dhcp_lease *lease, sd_dhcp_lease *lease,
bool conditional, bool conditional,
sd_dhcp_lease_info what, sd_dhcp_lease_server_type what,
sd_dhcp6_lease *lease6, sd_dhcp6_lease *lease6,
bool conditional6, bool conditional6,
int (*lease6_get_addr)(sd_dhcp6_lease*, const struct in6_addr**), int (*lease6_get_addr)(sd_dhcp6_lease*, const struct in6_addr**),
@ -4138,7 +4138,7 @@ int link_save(Link *link) {
NULL, NULL,
link->dhcp_lease, link->dhcp_lease,
link->network->dhcp_use_dns, link->network->dhcp_use_dns,
SD_DHCP_LEASE_DNS_SERVERS, SD_DHCP_LEASE_DNS,
dhcp6_lease, dhcp6_lease,
link->network->dhcp6_use_dns, link->network->dhcp6_use_dns,
sd_dhcp6_lease_get_dns, sd_dhcp6_lease_get_dns,
@ -4162,7 +4162,7 @@ int link_save(Link *link) {
link->ntp ?: link->network->ntp, link->ntp ?: link->network->ntp,
link->dhcp_lease, link->dhcp_lease,
link->network->dhcp_use_ntp, link->network->dhcp_use_ntp,
SD_DHCP_LEASE_NTP_SERVERS, SD_DHCP_LEASE_NTP,
dhcp6_lease, dhcp6_lease,
link->network->dhcp6_use_ntp, link->network->dhcp6_use_ntp,
sd_dhcp6_lease_get_ntp_addrs, sd_dhcp6_lease_get_ntp_addrs,
@ -4172,28 +4172,28 @@ int link_save(Link *link) {
link->network->sip, link->network->sip,
link->dhcp_lease, link->dhcp_lease,
link->network->dhcp_use_sip, link->network->dhcp_use_sip,
SD_DHCP_LEASE_SIP_SERVERS, SD_DHCP_LEASE_SIP,
false, NULL, NULL, NULL); false, NULL, NULL, NULL);
serialize_addresses(f, "POP3_SERVERS", NULL, serialize_addresses(f, "POP3", NULL,
link->network->pop3, link->network->pop3,
link->dhcp_lease, link->dhcp_lease,
true, true,
SD_DHCP_LEASE_POP3_SERVERS, SD_DHCP_LEASE_POP3,
false, NULL, NULL, NULL); false, NULL, NULL, NULL);
serialize_addresses(f, "SMTP_SERVERS", NULL, serialize_addresses(f, "SMTP", NULL,
link->network->smtp, link->network->smtp,
link->dhcp_lease, link->dhcp_lease,
true, true,
SD_DHCP_LEASE_SMTP_SERVERS, SD_DHCP_LEASE_SMTP,
false, NULL, NULL, NULL); false, NULL, NULL, NULL);
serialize_addresses(f, "LPR_SERVERS", NULL, serialize_addresses(f, "LPR", NULL,
link->network->lpr, link->network->lpr,
link->dhcp_lease, link->dhcp_lease,
true, true,
SD_DHCP_LEASE_LPR_SERVERS, SD_DHCP_LEASE_LPR,
false, NULL, NULL, NULL); false, NULL, NULL, NULL);
/************************************************************/ /************************************************************/

View File

@ -1611,7 +1611,7 @@ static int manager_save(Manager *m) {
return r; return r;
} }
r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses); r = sd_dhcp_lease_get_pop3(link->dhcp_lease, &addresses);
if (r > 0) { if (r > 0) {
r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local); r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
if (r < 0) if (r < 0)
@ -1619,7 +1619,7 @@ static int manager_save(Manager *m) {
} else if (r < 0 && r != -ENODATA) } else if (r < 0 && r != -ENODATA)
return r; return r;
r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses); r = sd_dhcp_lease_get_smtp(link->dhcp_lease, &addresses);
if (r > 0) { if (r > 0) {
r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local); r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local);
if (r < 0) if (r < 0)
@ -1627,7 +1627,7 @@ static int manager_save(Manager *m) {
} else if (r < 0 && r != -ENODATA) } else if (r < 0 && r != -ENODATA)
return r; return r;
r = sd_dhcp_lease_get_lpr_servers(link->dhcp_lease, &addresses); r = sd_dhcp_lease_get_lpr(link->dhcp_lease, &addresses);
if (r > 0) { if (r > 0) {
r = ordered_set_put_in4_addrv(lpr, addresses, r, in4_addr_is_non_local); r = ordered_set_put_in4_addrv(lpr, addresses, r, in4_addr_is_non_local);
if (r < 0) if (r < 0)

View File

@ -37,13 +37,13 @@ static const char* const duplicate_address_detection_address_family_table[_ADDRE
[ADDRESS_FAMILY_IPV6] = "ipv6", [ADDRESS_FAMILY_IPV6] = "ipv6",
}; };
static const char* const dhcp_lease_info_table[_SD_DHCP_LEASE_INFO_MAX] = { static const char* const dhcp_lease_server_type_table[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
[SD_DHCP_LEASE_DNS_SERVERS] = "DNS servers", [SD_DHCP_LEASE_DNS] = "DNS servers",
[SD_DHCP_LEASE_NTP_SERVERS] = "NTP servers", [SD_DHCP_LEASE_NTP] = "NTP servers",
[SD_DHCP_LEASE_SIP_SERVERS] = "SIP servers", [SD_DHCP_LEASE_SIP] = "SIP servers",
[SD_DHCP_LEASE_POP3_SERVERS] = "POP3 servers", [SD_DHCP_LEASE_POP3] = "POP3 servers",
[SD_DHCP_LEASE_SMTP_SERVERS] = "SMTP servers", [SD_DHCP_LEASE_SMTP] = "SMTP servers",
[SD_DHCP_LEASE_LPR_SERVERS] = "LPR servers", [SD_DHCP_LEASE_LPR] = "LPR servers",
}; };
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES); DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
@ -52,7 +52,7 @@ DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily); DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFamily);
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family, DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
AddressFamily, "Failed to parse option"); AddressFamily, "Failed to parse option");
DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_info, sd_dhcp_lease_info); DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type);
int config_parse_address_family_with_kernel( int config_parse_address_family_with_kernel(
const char* unit, const char* unit,

View File

@ -40,8 +40,8 @@ AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pur
const char *duplicate_address_detection_address_family_to_string(AddressFamily b) _const_; const char *duplicate_address_detection_address_family_to_string(AddressFamily b) _const_;
AddressFamily duplicate_address_detection_address_family_from_string(const char *s) _pure_; AddressFamily duplicate_address_detection_address_family_from_string(const char *s) _pure_;
const char *dhcp_lease_info_to_string(sd_dhcp_lease_info info) _const_; const char *dhcp_lease_server_type_to_string(sd_dhcp_lease_server_type t) _const_;
sd_dhcp_lease_info dhcp_lease_info_from_string(const char *s) _pure_; sd_dhcp_lease_server_type dhcp_lease_server_type_from_string(const char *s) _pure_;
int kernel_route_expiration_supported(void); int kernel_route_expiration_supported(void);

View File

@ -735,9 +735,12 @@ int boot_entries_load_config_auto(
return boot_entries_load_config(esp_where, xbootldr_where, config); return boot_entries_load_config(esp_where, xbootldr_where, config);
} }
#if ENABLE_EFI int boot_entries_augment_from_loader(
int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) { BootConfig *config,
static const char * const title_table[] = { char **found_by_loader,
bool only_auto) {
static const char *const title_table[] = {
/* Pretty names for a few well-known automatically discovered entries. */ /* Pretty names for a few well-known automatically discovered entries. */
"auto-osx", "macOS", "auto-osx", "macOS",
"auto-windows", "Windows Boot Manager", "auto-windows", "Windows Boot Manager",
@ -746,22 +749,14 @@ int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) {
"auto-reboot-to-firmware-setup", "Reboot Into Firmware Interface", "auto-reboot-to-firmware-setup", "Reboot Into Firmware Interface",
}; };
_cleanup_strv_free_ char **found_by_loader = NULL;
size_t n_allocated; size_t n_allocated;
char **i; char **i;
int r;
assert(config); assert(config);
/* Let's add the entries discovered by the boot loader to the end of our list, unless they are /* Let's add the entries discovered by the boot loader to the end of our list, unless they are
* already included there. */ * already included there. */
r = efi_loader_get_entries(&found_by_loader);
if (IN_SET(r, -ENOENT, -EOPNOTSUPP))
return log_debug_errno(r, "Boot loader reported no entries.");
if (r < 0)
return log_error_errno(r, "Failed to determine entries reported by boot loader: %m");
n_allocated = config->n_entries; n_allocated = config->n_entries;
STRV_FOREACH(i, found_by_loader) { STRV_FOREACH(i, found_by_loader) {
@ -803,7 +798,6 @@ int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) {
return 0; return 0;
} }
#endif
/********************************************************************************/ /********************************************************************************/

View File

@ -76,13 +76,7 @@ static inline BootEntry* boot_config_default_entry(BootConfig *config) {
void boot_config_free(BootConfig *config); void boot_config_free(BootConfig *config);
int boot_entries_load_config(const char *esp_path, const char *xbootldr_path, BootConfig *config); int boot_entries_load_config(const char *esp_path, const char *xbootldr_path, BootConfig *config);
int boot_entries_load_config_auto(const char *override_esp_path, const char *override_xbootldr_path, BootConfig *config); int boot_entries_load_config_auto(const char *override_esp_path, const char *override_xbootldr_path, BootConfig *config);
#if ENABLE_EFI int boot_entries_augment_from_loader(BootConfig *config, char **list, bool only_auto);
int boot_entries_augment_from_loader(BootConfig *config, bool only_auto);
#else
static inline int boot_entries_augment_from_loader(BootConfig *config, bool only_auto) {
return -EOPNOTSUPP;
}
#endif
static inline const char* boot_entry_title(const BootEntry *entry) { static inline const char* boot_entry_title(const BootEntry *entry) {
return entry->show_title ?: entry->title ?: entry->id; return entry->show_title ?: entry->title ?: entry->id;

View File

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#include <stdlib.h> #include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "alloc-util.h" #include "alloc-util.h"
@ -11,6 +12,7 @@
#include "io-util.h" #include "io-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "sort-util.h" #include "sort-util.h"
#include "stat-util.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-util.h" #include "string-util.h"
#include "utf8.h" #include "utf8.h"
@ -28,7 +30,8 @@
#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff #define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001 #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
#define boot_option__contents { \ #define boot_option__contents \
{ \
uint32_t attr; \ uint32_t attr; \
uint16_t path_len; \ uint16_t path_len; \
uint16_t title[]; \ uint16_t title[]; \
@ -49,7 +52,8 @@ struct drive_path {
uint8_t signature_type; uint8_t signature_type;
} _packed_; } _packed_;
#define device_path__contents { \ #define device_path__contents \
{ \
uint8_t type; \ uint8_t type; \
uint8_t sub_type; \ uint8_t sub_type; \
uint16_t length; \ uint16_t length; \
@ -63,19 +67,24 @@ struct device_path device_path__contents;
struct device_path__packed device_path__contents _packed_; struct device_path__packed device_path__contents _packed_;
assert_cc(sizeof(struct device_path) == sizeof(struct device_path__packed)); assert_cc(sizeof(struct device_path) == sizeof(struct device_path__packed));
int efi_reboot_to_firmware_supported(void) { int efi_reboot_to_firmware_supported(void) {
_cleanup_free_ void *v = NULL; _cleanup_free_ void *v = NULL;
static int cache = -1;
uint64_t b; uint64_t b;
size_t s; size_t s;
int r; int r;
if (!is_efi_boot()) if (cache > 0)
return 0;
if (cache == 0)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!is_efi_boot())
goto not_supported;
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s); r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndicationsSupported", NULL, &v, &s);
if (r == -ENOENT) /* variable doesn't exist? it's not supported then */ if (r == -ENOENT)
return -EOPNOTSUPP; goto not_supported; /* variable doesn't exist? it's not supported then */
if (r < 0) if (r < 0)
return r; return r;
if (s != sizeof(uint64_t)) if (s != sizeof(uint64_t))
@ -83,36 +92,68 @@ int efi_reboot_to_firmware_supported(void) {
b = *(uint64_t*) v; b = *(uint64_t*) v;
if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)) if (!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI))
return -EOPNOTSUPP; /* bit unset? it's not supported then */ goto not_supported; /* bit unset? it's not supported then */
cache = 1;
return 0; return 0;
not_supported:
cache = 0;
return -EOPNOTSUPP;
} }
static int get_os_indications(uint64_t *os_indication) { static int get_os_indications(uint64_t *ret) {
static struct stat cache_stat = {};
_cleanup_free_ void *v = NULL; _cleanup_free_ void *v = NULL;
_cleanup_free_ char *fn = NULL;
static uint64_t cache;
struct stat new_stat;
size_t s; size_t s;
int r; int r;
assert(ret);
/* Let's verify general support first */ /* Let's verify general support first */
r = efi_reboot_to_firmware_supported(); r = efi_reboot_to_firmware_supported();
if (r < 0) if (r < 0)
return r; return r;
fn = efi_variable_path(EFI_VENDOR_GLOBAL, "OsIndications");
if (!fn)
return -ENOMEM;
/* stat() the EFI variable, to see if the mtime changed. If it did we need to cache again. */
if (stat(fn, &new_stat) < 0) {
if (errno != ENOENT)
return -errno;
/* Doesn't exist? Then we can exit early (also see below) */
*ret = 0;
return 0;
} else if (stat_inode_unmodified(&new_stat, &cache_stat)) {
/* inode didn't change, we can return the cached value */
*ret = cache;
return 0;
}
r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s); r = efi_get_variable(EFI_VENDOR_GLOBAL, "OsIndications", NULL, &v, &s);
if (r == -ENOENT) { if (r == -ENOENT) {
/* Some firmware implementations that do support OsIndications and report that with /* Some firmware implementations that do support OsIndications and report that with
* OsIndicationsSupported will remove the OsIndications variable when it is unset. Let's pretend it's 0 * OsIndicationsSupported will remove the OsIndications variable when it is unset. Let's
* then, to hide this implementation detail. Note that this call will return -ENOENT then only if the * pretend it's 0 then, to hide this implementation detail. Note that this call will return
* support for OsIndications is missing entirely, as determined by efi_reboot_to_firmware_supported() * -ENOENT then only if the support for OsIndications is missing entirely, as determined by
* above. */ * efi_reboot_to_firmware_supported() above. */
*os_indication = 0; *ret = 0;
return 0; return 0;
} else if (r < 0) }
if (r < 0)
return r; return r;
else if (s != sizeof(uint64_t)) if (s != sizeof(uint64_t))
return -EINVAL; return -EINVAL;
*os_indication = *(uint64_t *)v; cache_stat = new_stat;
*ret = cache = *(uint64_t *)v;
return 0; return 0;
} }

View File

@ -22,6 +22,7 @@
#include "journal-internal.h" #include "journal-internal.h"
#include "journal-util.h" #include "journal-util.h"
#include "json.h" #include "json.h"
#include "locale-util.h"
#include "log.h" #include "log.h"
#include "logs-show.h" #include "logs-show.h"
#include "macro.h" #include "macro.h"
@ -39,6 +40,7 @@
#include "time-util.h" #include "time-util.h"
#include "utf8.h" #include "utf8.h"
#include "util.h" #include "util.h"
#include "web-util.h"
/* up to three lines (each up to 100 characters) or 300 characters, whichever is less */ /* up to three lines (each up to 100 characters) or 300 characters, whichever is less */
#define PRINT_LINE_THRESHOLD 3 #define PRINT_LINE_THRESHOLD 3
@ -47,12 +49,16 @@
#define JSON_THRESHOLD 4096U #define JSON_THRESHOLD 4096U
static int print_catalog(FILE *f, sd_journal *j) { static int print_catalog(FILE *f, sd_journal *j) {
int r;
_cleanup_free_ char *t = NULL, *z = NULL; _cleanup_free_ char *t = NULL, *z = NULL;
int r;
assert(j);
r = sd_journal_get_catalog(j, &t); r = sd_journal_get_catalog(j, &t);
if (r == -ENOENT)
return 0;
if (r < 0) if (r < 0)
return r; return log_error_errno(r, "Failed to find catalog entry: %m");
z = strreplace(strstrip(t), "\n", "\n-- "); z = strreplace(strstrip(t), "\n", "\n-- ");
if (!z) if (!z)
@ -62,6 +68,48 @@ static int print_catalog(FILE *f, sd_journal *j) {
fputs(z, f); fputs(z, f);
fputc('\n', f); fputc('\n', f);
return 1;
}
static int url_from_catalog(sd_journal *j, char **ret) {
_cleanup_free_ char *t = NULL, *url = NULL;
const char *weblink;
int r;
assert(j);
assert(ret);
r = sd_journal_get_catalog(j, &t);
if (r == -ENOENT)
goto notfound;
if (r < 0)
return log_error_errno(r, "Failed to find catalog entry: %m");
weblink = startswith(t, "Documentation:");
if (!weblink) {
weblink = strstr(t + 1, "\nDocumentation:");
if (!weblink)
goto notfound;
weblink += 15;
}
/* Skip whitespace to value */
weblink += strspn(weblink, " \t");
/* Cut out till next whitespace/newline */
url = strndup(weblink, strcspn(weblink, WHITESPACE));
if (!url)
return log_oom();
if (!documentation_url_is_valid(url))
goto notfound;
*ret = TAKE_PTR(url);
return 1;
notfound:
*ret = NULL;
return 0; return 0;
} }
@ -128,9 +176,6 @@ static int field_set_test(const Set *fields, const char *name, size_t n) {
return 1; return 1;
s = strndupa(name, n); s = strndupa(name, n);
if (!s)
return log_oom();
return set_contains(fields, s); return set_contains(fields, s);
} }
@ -374,10 +419,13 @@ static int output_short(
int r; int r;
const void *data; const void *data;
size_t length; size_t length, n = 0;
size_t n = 0; _cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL,
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *transport = NULL, *config_file = NULL, *unit = NULL, *user_unit = NULL; *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *transport = NULL,
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0, transport_len = 0, config_file_len = 0, unit_len = 0, user_unit_len = 0; *config_file = NULL, *unit = NULL, *user_unit = NULL, *documentation_url = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0,
realtime_len = 0, monotonic_len = 0, priority_len = 0, transport_len = 0, config_file_len = 0,
unit_len = 0, user_unit_len = 0, documentation_url_len = 0;
int p = LOG_INFO; int p = LOG_INFO;
bool ellipsized = false, audit; bool ellipsized = false, audit;
const ParseFieldVec fields[] = { const ParseFieldVec fields[] = {
@ -394,6 +442,7 @@ static int output_short(
PARSE_FIELD_VEC_ENTRY("CONFIG_FILE=", &config_file, &config_file_len), PARSE_FIELD_VEC_ENTRY("CONFIG_FILE=", &config_file, &config_file_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_UNIT=", &unit, &unit_len), PARSE_FIELD_VEC_ENTRY("_SYSTEMD_UNIT=", &unit, &unit_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_USER_UNIT=", &user_unit, &user_unit_len), PARSE_FIELD_VEC_ENTRY("_SYSTEMD_USER_UNIT=", &user_unit, &user_unit_len),
PARSE_FIELD_VEC_ENTRY("DOCUMENTATION=", &documentation_url, &documentation_url_len),
}; };
size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0}; size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0};
@ -482,11 +531,42 @@ static int output_short(
n += fake_pid_len + 2; n += fake_pid_len + 2;
} }
fputs(": ", f);
if (urlify_enabled()) {
_cleanup_free_ char *c = NULL;
/* Insert a hyperlink to a documentation URL before the message. Note that we don't make the
* whole message a hyperlink, since otherwise the whole screen might end up being just
* hyperlinks. Moreover, we want to be able to highlight parts of the message (such as the
* config file, see below) hence let's keep the documentation URL link separate. */
if (documentation_url && shall_print(documentation_url, documentation_url_len, flags)) {
c = strndup(documentation_url, documentation_url_len);
if (!c)
return log_oom();
if (!documentation_url_is_valid(c)) /* Eat up invalid links */
c = mfree(c);
}
if (!c)
(void) url_from_catalog(j, &c); /* Acquire from catalog if not embedded in log message itself */
if (c) {
_cleanup_free_ char *urlified = NULL;
if (terminal_urlify(c, special_glyph(SPECIAL_GLYPH_EXTERNAL_LINK), &urlified) >= 0) {
fputs(urlified, f);
fputc(' ', f);
}
}
}
if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len)) { if (!(flags & OUTPUT_SHOW_ALL) && !utf8_is_printable(message, message_len)) {
char bytes[FORMAT_BYTES_MAX]; char bytes[FORMAT_BYTES_MAX];
fprintf(f, ": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len)); fprintf(f, "[%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
} else { } else {
fputs(": ", f);
/* URLify config_file string in message, if the message starts with it. /* URLify config_file string in message, if the message starts with it.
* Skip URLification if the highlighted pattern overlaps. */ * Skip URLification if the highlighted pattern overlaps. */
@ -522,7 +602,7 @@ static int output_short(
} }
if (flags & OUTPUT_CATALOG) if (flags & OUTPUT_CATALOG)
print_catalog(f, j); (void) print_catalog(f, j);
return ellipsized; return ellipsized;
} }
@ -641,7 +721,7 @@ static int output_verbose(
return r; return r;
if (flags & OUTPUT_CATALOG) if (flags & OUTPUT_CATALOG)
print_catalog(f, j); (void) print_catalog(f, j);
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@
#include "terminal-util.h" #include "terminal-util.h"
#include "util.h" #include "util.h"
static bool urlify_enabled(void) { bool urlify_enabled(void) {
static int cached_urlify_enabled = -1; static int cached_urlify_enabled = -1;
/* Unfortunately 'less' doesn't support links like this yet 😭, hence let's disable this as long as there's a /* Unfortunately 'less' doesn't support links like this yet 😭, hence let's disable this as long as there's a

View File

@ -5,6 +5,8 @@ void print_separator(void);
int file_url_from_path(const char *path, char **ret); int file_url_from_path(const char *path, char **ret);
bool urlify_enabled(void);
int terminal_urlify(const char *url, const char *text, char **ret); int terminal_urlify(const char *url, const char *text, char **ret);
int terminal_urlify_path(const char *path, const char *text, char **ret); int terminal_urlify_path(const char *path, const char *text, char **ret);
int terminal_urlify_man(const char *page, const char *section, char **ret); int terminal_urlify_man(const char *page, const char *section, char **ret);

View File

@ -199,7 +199,7 @@ static bool lookup_paths_mtime_exclude(const LookupPaths *lp, const char *path)
streq_ptr(path, lp->runtime_control); streq_ptr(path, lp->runtime_control);
} }
static bool lookup_paths_mtime_good(const LookupPaths *lp, usec_t mtime) { bool lookup_paths_mtime_good(const LookupPaths *lp, usec_t mtime) {
char **dir; char **dir;
STRV_FOREACH(dir, (char**) lp->search_path) { STRV_FOREACH(dir, (char**) lp->search_path) {

View File

@ -43,6 +43,7 @@ bool unit_type_may_template(UnitType type) _const_;
int unit_symlink_name_compatible(const char *symlink, const char *target, bool instance_propagation); int unit_symlink_name_compatible(const char *symlink, const char *target, bool instance_propagation);
int unit_validate_alias_symlink_and_warn(const char *filename, const char *target); int unit_validate_alias_symlink_and_warn(const char *filename, const char *target);
bool lookup_paths_mtime_good(const LookupPaths *lp, usec_t mtime);
int unit_file_build_name_map( int unit_file_build_name_map(
const LookupPaths *lp, const LookupPaths *lp,
usec_t *ret_time, usec_t *ret_time,

View File

@ -130,6 +130,7 @@ static const char *arg_kill_who = NULL;
static int arg_signal = SIGTERM; static int arg_signal = SIGTERM;
static char *arg_root = NULL; static char *arg_root = NULL;
static usec_t arg_when = 0; static usec_t arg_when = 0;
static const char *arg_reboot_argument = NULL;
static enum action { static enum action {
ACTION_SYSTEMCTL, ACTION_SYSTEMCTL,
ACTION_HALT, ACTION_HALT,
@ -3556,10 +3557,23 @@ static int start_special(int argc, char *argv[], void *userdata) {
if (r < 0) if (r < 0)
return r; return r;
if (a == ACTION_REBOOT && argc > 1) { if (a == ACTION_REBOOT) {
r = update_reboot_parameter_and_warn(argv[1], false); const char *arg = NULL;
if (argc > 1) {
if (arg_reboot_argument)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Both --reboot-argument= and positional argument passed to reboot command, refusing.");
log_notice("Positional argument to reboot command is deprecated, please use --reboot-argument= instead. Accepting anyway.");
arg = argv[1];
} else
arg = arg_reboot_argument;
if (arg) {
r = update_reboot_parameter_and_warn(arg, false);
if (r < 0) if (r < 0)
return r; return r;
}
} else if (a == ACTION_KEXEC) { } else if (a == ACTION_KEXEC) {
r = load_kexec_kernel(); r = load_kexec_kernel();
@ -7708,7 +7722,7 @@ static int systemctl_help(void) {
" emergency Enter system emergency mode\n" " emergency Enter system emergency mode\n"
" halt Shut down and halt the system\n" " halt Shut down and halt the system\n"
" poweroff Shut down and power-off the system\n" " poweroff Shut down and power-off the system\n"
" reboot [ARG] Shut down and reboot the system\n" " reboot Shut down and reboot the system\n"
" kexec Shut down and reboot the system with kexec\n" " kexec Shut down and reboot the system with kexec\n"
" exit [EXIT_CODE] Request user instance or container exit\n" " exit [EXIT_CODE] Request user instance or container exit\n"
" switch-root ROOT [INIT] Change to a different root file system\n" " switch-root ROOT [INIT] Change to a different root file system\n"
@ -8026,6 +8040,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
ARG_WITH_DEPENDENCIES, ARG_WITH_DEPENDENCIES,
ARG_WAIT, ARG_WAIT,
ARG_WHAT, ARG_WHAT,
ARG_REBOOT_ARG,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -8079,6 +8094,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "message", required_argument, NULL, ARG_MESSAGE }, { "message", required_argument, NULL, ARG_MESSAGE },
{ "show-transaction", no_argument, NULL, 'T' }, { "show-transaction", no_argument, NULL, 'T' },
{ "what", required_argument, NULL, ARG_WHAT }, { "what", required_argument, NULL, ARG_WHAT },
{ "reboot-argument", required_argument, NULL, ARG_REBOOT_ARG },
{} {}
}; };
@ -8474,6 +8490,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break; break;
} }
case ARG_REBOOT_ARG:
arg_reboot_argument = optarg;
break;
case '.': case '.':
/* Output an error mimicking getopt, and print a hint afterwards */ /* Output an error mimicking getopt, and print a hint afterwards */
log_error("%s: invalid option -- '.'", program_invocation_name); log_error("%s: invalid option -- '.'", program_invocation_name);

View File

@ -33,15 +33,16 @@ typedef struct sd_dhcp_route sd_dhcp_route;
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease); sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease);
sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease); sd_dhcp_lease *sd_dhcp_lease_unref(sd_dhcp_lease *lease);
typedef enum sd_dhcp_lease_info { typedef enum sd_dhcp_lease_server_type {
SD_DHCP_LEASE_DNS_SERVERS = 0, SD_DHCP_LEASE_DNS,
SD_DHCP_LEASE_NTP_SERVERS, SD_DHCP_LEASE_NTP,
SD_DHCP_LEASE_SIP_SERVERS, SD_DHCP_LEASE_SIP,
SD_DHCP_LEASE_POP3_SERVERS, SD_DHCP_LEASE_POP3,
SD_DHCP_LEASE_SMTP_SERVERS, SD_DHCP_LEASE_SMTP,
SD_DHCP_LEASE_LPR_SERVERS, SD_DHCP_LEASE_LPR,
_SD_DHCP_LEASE_INFO_MAX, _SD_DHCP_LEASE_SERVER_TYPE_MAX,
} sd_dhcp_lease_info; _SD_DHCP_LEASE_SERVER_TYPE_INVALID = -1,
} sd_dhcp_lease_server_type;
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime); int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
@ -52,13 +53,13 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr); int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_info what, const struct in_addr **addr); int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_server_type what, const struct in_addr **addr);
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_lpr_servers(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains); int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);

View File

@ -52,7 +52,7 @@ int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_set_servers( int sd_dhcp_server_set_servers(
sd_dhcp_server *server, sd_dhcp_server *server,
sd_dhcp_lease_info what, sd_dhcp_lease_server_type what,
const struct in_addr addresses[], const struct in_addr addresses[],
size_t n_addresses); size_t n_addresses);

View File

@ -107,6 +107,7 @@ static void dump_special_glyphs(void) {
dump_glyph(SPECIAL_GLYPH_MU); dump_glyph(SPECIAL_GLYPH_MU);
dump_glyph(SPECIAL_GLYPH_CHECK_MARK); dump_glyph(SPECIAL_GLYPH_CHECK_MARK);
dump_glyph(SPECIAL_GLYPH_CROSS_MARK); dump_glyph(SPECIAL_GLYPH_CROSS_MARK);
dump_glyph(SPECIAL_GLYPH_EXTERNAL_LINK);
dump_glyph(SPECIAL_GLYPH_ECSTATIC_SMILEY); dump_glyph(SPECIAL_GLYPH_ECSTATIC_SMILEY);
dump_glyph(SPECIAL_GLYPH_HAPPY_SMILEY); dump_glyph(SPECIAL_GLYPH_HAPPY_SMILEY);
dump_glyph(SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY); dump_glyph(SPECIAL_GLYPH_SLIGHTLY_HAPPY_SMILEY);

View File

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
set -e
TEST_DESCRIPTION="test StartStopNoReload"
. $TEST_BASE_DIR/test-functions
do_test "$@" 48

View File

@ -395,9 +395,9 @@ run_nspawn() {
dwarn "nspawn doesn't support SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=hybrid, skipping" dwarn "nspawn doesn't support SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=hybrid, skipping"
exit exit
elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "yes" || "$UNIFIED_CGROUP_HIERARCHY" = "no" ]]; then
_nspawn_pre=("${nspawn_pre[@]}" env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY) _nspawn_pre=("${_nspawn_pre[@]}" env SYSTEMD_NSPAWN_UNIFIED_HIERARCHY=$UNIFIED_CGROUP_HIERARCHY)
elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then elif [[ "$UNIFIED_CGROUP_HIERARCHY" = "default" ]]; then
_nspawn_pre=("${nspawn_pre[@]}" env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY) _nspawn_pre=("${_nspawn_pre[@]}" env --unset=UNIFIED_CGROUP_HIERARCHY --unset=SYSTEMD_NSPAWN_UNIFIED_HIERARCHY)
else else
dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]" dfatal "Unknown UNIFIED_CGROUP_HIERARCHY. Got $UNIFIED_CGROUP_HIERARCHY, expected [yes|no|hybrid|default]"
exit 1 exit 1

View File

@ -0,0 +1,7 @@
[Unit]
Description=TEST-48-START-STOP-NO-RELOAD
[Service]
ExecStartPre=rm -f /failed /testok
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
Type=oneshot

38
test/units/testsuite-48.sh Executable file
View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
set -ex
cat > /run/systemd/system/testservice-48.target <<EOF
[Unit]
Wants=testservice-48.service
EOF
systemctl daemon-reload
systemctl start testservice-48.target
# The filesystem on the test image, despite being ext4, seems to have a mtime
# granularity of one second, which means the manager's unit cache won't be
# marked as dirty when writing the unit file, unless we wait at least a full
# second after the previous daemon-reload.
# May 07 23:12:20 systemd-testsuite testsuite-48.sh[30]: + cat
# May 07 23:12:20 systemd-testsuite testsuite-48.sh[30]: + ls -l --full-time /etc/systemd/system/testservice-48.service
# May 07 23:12:20 systemd-testsuite testsuite-48.sh[52]: -rw-r--r-- 1 root root 50 2020-05-07 23:12:20.000000000 +0100 /
# May 07 23:12:20 systemd-testsuite testsuite-48.sh[30]: + stat -f --format=%t /etc/systemd/system/testservice-48.servic
# May 07 23:12:20 systemd-testsuite testsuite-48.sh[53]: ef53
sleep 1.1
cat > /run/systemd/system/testservice-48.service <<EOF
[Service]
ExecStart=/bin/sleep infinity
Type=exec
EOF
systemctl start testservice-48.service
systemctl is-active testservice-48.service
echo OK > /testok
exit 0