# - Patch0000-0499: backported patches from upstream
# - Patch0500-9999: downstream-only patches
- "sed -ri '/^Patch0[0-4][0-9]{2}+\\:.+\\.patch/d' .packit_rpm/systemd.spec"
- # Build the RPMs with -Werror to catch possible compiler warnings
- - "sed -i 's/^%meson /%meson --werror /' .packit_rpm/systemd.spec"
+ # Build the RPMs with -Werror to catch possible compiler warnings. Since
+ # --werror in meson doesn't seem to work with -Db_lto=true [0], let's use
+ # -Dc_args= and -Dcpp_args= instead.
+ #
+ # Exceptions:
+ # - use -Wno-deprecated-declarations to get around mallinfo() use in
+ # basic/selinux-util.c
+ # - don't use -Werror on x86 architectures, otherwise all function checks
+ # will fail (with error: cast from pointer to integer of different size)
+ #
+ # [0] https://github.com/mesonbuild/meson/issues/7360
+ - 'sed -i "/^CONFIGURE_OPTS=(/a%ifnarch i386 i686\n-Dc_args=\"-Werror -Wno-deprecated-declarations\" -Dcpp_args=\"-Werror -Wno-deprecated-declarations\"\n%endif" .packit_rpm/systemd.spec'
jobs:
- job: copr_build
Note that the build prefix for systemd must be /usr. (Moreover,
packages systemd relies on — such as D-Bus — really should use the same
prefix, otherwise you are on your own.) -Dsplit-usr=false (which is the
- default and does not need to be specified) is the recommended setting,
- and -Dsplit-usr=true should be used on systems which have /usr on a
- separate partition.
+ default and does not need to be specified) is the recommended setting.
+ -Dsplit-usr=true can be used to give a semblance of support for systems
+ with programs installed split between / and /usr. Moving everything
+ under /usr is strongly encouraged.
Additional packages are necessary to run some tests:
- busybox (used by test/TEST-13-NSPAWN-SMOKE)
| `/run` | File hierarchy change | yes | yes | numerous | yes | OpenSUSE, Debian, ArchLinux | no |
| [Generators](https://www.freedesktop.org/software/systemd/man/systemd.generator.html) | Subprocess | yes | yes | - | no | - | no |
| [System Updates](https://www.freedesktop.org/software/systemd/man/systemd.offline-updates.html) | System Mode | yes | yes | - | no | - | no |
-| [Presets](https://freedesktop.org/wiki/Software/systemd/Preset) | File format | yes | yes | - | no | - | no |
+| [Presets](https://www.freedesktop.org/software/systemd/man/systemd.preset.html) | File format | yes | yes | - | no | - | no |
| Udev rules | File format | yes | yes | numerous | no | no | partially |
in b interactive);
FlushDevices(in b interactive);
PowerOff(in b interactive);
+ PowerOffWithFlags(in t flags);
Reboot(in b interactive);
+ RebootWithFlags(in t flags);
Halt(in b interactive);
+ HaltWithFlags(in t flags);
Suspend(in b interactive);
+ SuspendWithFlags(in t flags);
Hibernate(in b interactive);
+ HibernateWithFlags(in t flags);
HybridSleep(in b interactive);
+ HybridSleepWithFlags(in t flags);
SuspendThenHibernate(in b interactive);
+ SuspendThenHibernateWithFlags(in t flags);
CanPowerOff(out s result);
CanReboot(out s result);
CanHalt(out s result);
<variablelist class="dbus-method" generated="True" extra-ref="PowerOff()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="PowerOffWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="Reboot()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="RebootWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="Halt()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="HaltWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="Suspend()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="SuspendWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="Hibernate()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="HibernateWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="HybridSleep()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="HybridSleepWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="SuspendThenHibernate()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="SuspendThenHibernateWithFlags()"/>
+
<variablelist class="dbus-method" generated="True" extra-ref="CanPowerOff()"/>
<variablelist class="dbus-method" generated="True" extra-ref="CanReboot()"/>
using an RTC timer and hibernated. The only argument is the polkit interactivity boolean
<varname>interactive</varname> (see below). The main purpose of these calls is that they enforce
polkit policy and hence allow powering off/rebooting/suspending/hibernating even by unprivileged
- users. They also enforce inhibition locks. UIs should expose these calls as the primary mechanism to
- poweroff/reboot/suspend/hibernate the machine.</para>
+ users. They also enforce inhibition locks for non-privileged users. UIs should expose these calls
+ as the primary mechanism to poweroff/reboot/suspend/hibernate the machine. Methods
+ <function>PowerOffWithFlags()</function>, <function>RebootWithFlags()</function>,
+ <function>HaltWithFlags()</function>, <function>SuspendWithFlags()</function>,
+ <function>HibernateWithFlags()</function>, <function>HybridSleepWithFlags()</function> and
+ <function>SuspendThenHibernateWithFlags()</function> add <varname>flags</varname> to allow for
+ extendability, defined as follows:</para>
+ <programlisting>
+#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0)
+ </programlisting>
+ <para> When the <varname>flags</varname> is 0 then these methods behave just like the versions
+ without flags. When <constant>SD_LOGIND_ROOT_CHECK_INHIBITORS</constant> (0x01) is set, active
+ inhibitors are honoured for privileged users too.</para>
<para><function>SetRebootParameter()</function> sets a parameter for a subsequent reboot operation.
See the description of <command>reboot</command> in
ResetStatistics();
FlushCaches();
ResetServerFeatures();
+ GetMulticastHosts(out a(stiiay) UNNAMED);
properties:
readonly s LLMNRHostname = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
<!--method ResetServerFeatures is not documented!-->
+ <!--method GetMulticastHosts is not documented!-->
+
<!--property DNSSECNegativeTrustAnchors is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-method" generated="True" extra-ref="ResetServerFeatures()"/>
+ <variablelist class="dbus-method" generated="True" extra-ref="GetMulticastHosts()"/>
+
<variablelist class="dbus-property" generated="True" extra-ref="LLMNRHostname"/>
<variablelist class="dbus-property" generated="True" extra-ref="LLMNR"/>
automatically, an explicit reverting is not necessary in that case.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><command>show-multicast</command></term>
+
+ <listitem><para>Display the discovered LLMNR and mDNS hostnames along with their IPv4/IPv6 addresses.
+ </para></listitem>
+ </varlistentry>
+
<xi:include href="systemctl.xml" xpointer="log-level" />
</variablelist>
</refsect1>
<para>For more information on the preset policy format, see
<citerefentry><refentrytitle>systemd.preset</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- For more information on the concept of presets, please consult the
- <ulink url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Preset</ulink>
- document.</para>
+ </para>
</listitem>
</varlistentry>
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>TxQueueLength=</varname></term>
+ <term><varname>TransmitQueues=</varname></term>
+ <listitem>
+ <para>Specifies the device's number of transmit queues. An integer in the range 1…4096.
+ When unset, the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>ReceiveQueues=</varname></term>
+ <listitem>
+ <para>Specifies the device's number of receive queues. An integer in the range 1…4096.
+ When unset, the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><varname>TransmitQueueLength=</varname></term>
<listitem>
<para>Specifies the transmit queue length of the device in number of packets. An unsigned integer
in the range 0…4294967294. When unset, the kernel's default will be used.</para>
integer in the range 0…4294967294. Defaults to unset.</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term><varname>TransmitQueues=</varname></term>
- <listitem>
- <para>Specifies the devices's number of transmit queues. An integer in the range 1…4096.
- When unset, the kernel's default will be used.</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><varname>ReceiveQueues=</varname></term>
- <listitem>
- <para>Specifies the devices's number of receive queues. An integer in the range 1…4096.
- When unset, the kernel's default will be used.</para>
- </listitem>
- </varlistentry>
<varlistentry>
<term><varname>RequiredForOnline=</varname></term>
<listitem>
<refsect1>
<title>Description</title>
- <para>Preset files may be used to encode policy which units shall
- be enabled by default and which ones shall be disabled. They are
- read by <command>systemctl preset</command> (for more information
- see
- <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>)
- which uses this information to enable or disable a unit according
- to preset policy. <command>systemctl preset</command> is used by
- the post install scriptlets of RPM packages (or other OS package
- formats), to enable/disable specific units by default on package
- installation, enforcing distribution, spin or administrator preset
- policy. This allows choosing a certain set of units to be
- enabled/disabled even before installing the actual package.</para>
-
- <para>For more information on the preset logic please have a look
- at the <ulink
- url="https://www.freedesktop.org/wiki/Software/systemd/Preset">Presets</ulink>
- document.</para>
-
- <para>It is not recommended to ship preset files within the
- respective software packages implementing the units, but rather
- centralize them in a distribution or spin default policy, which
- can be amended by administrator policy.</para>
+ <para>Preset files may be used to encode policy which units shall be enabled by default and which ones
+ shall be disabled. They are read by <command>systemctl preset</command> which uses this information to
+ enable or disable a unit. Depending on that policy, <command>systemctl preset</command> is identical to
+ <command>systemctl enable</command> or <command>systemctl disable</command>.
+
+ <command>systemctl preset</command> is used by the post install scriptlets of rpm packages (or other OS
+ package formats), to enable/disable specific units by default on package installation, enforcing
+ distribution, spin or administrator preset policy. This allows choosing a certain set of units to be
+ enabled/disabled even before installing the actual package. For more information, see
+ <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
+
+ <para>It is not recommended to ship preset files within the respective software packages implementing the
+ units, but rather centralize them in a distribution or spin default policy, which can be amended by
+ administrator policy, see below.</para>
<para>If no preset files exist, <command>systemctl
preset</command> will enable all units that are installed by
override all other preset policy files.</para>
</refsect1>
+ <refsect1>
+ <title>Motiviation for the preset logic</title>
+
+ <para>Different distributions have different policies on which services shall be enabled by default when
+ the package they are shipped in is installed. On Fedora all services stay off by default, so that
+ installing a package will not cause a service to be enabled (with some exceptions). On Debian all
+ services are immediately enabled by default, so that installing a package will cause its services to be
+ enabled right-away.</para>
+
+ <para>Even within a single distribution, different spins (flavours, remixes, whatever you might want to
+ call them) of a distribution also have different policies on what services to enable, and what services
+ to leave off. For example, Fedora Workstation will enable <command>gdm</command> as display manager by
+ default, while the Fedora KDE spin will enable <command>sddm</command> instead.</para>
+
+ <para>Different sites might also have different policies what to turn on by default and what to turn
+ off. For example, one administrator would prefer to enforce the policy of "<command>sshd</command> should
+ be always on, but everything else off", while another one might say "<command>snmpd</command> always on,
+ and for everything else use the distribution policy defaults".</para>
+
+ <para>Traditionally, policy about which services shall be enabled were implemented in each package
+ individually. This made it cumbersome to implement different policies per spin or per site, or to create
+ software packages that do the right thing on more than one distribution. The enablement mechanism was
+ also encoding the enablement policy.</para>
+
+ <para>The preset mechanism allows clean separation of the enablement mechanism (inside the package
+ scriptlets, by invoking <command>systemctl preset</command>) and enablement policy (centralized in the
+ preset files), and lifts the configuration out of individual packages. Preset files may be written for
+ specific distributions, for specific spins or for specific sites, in order to enforce different policies
+ as needed. It is recommended to apply the policy encoded in preset files in package installation
+ scriptlets.</para>
+ </refsect1>
+
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-delta</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
+
+ <para><citerefentry><refentrytitle>daemon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ has a discussion of packaging scriptlets.</para>
+
+ <para>Fedora page introducing the use of presets:
+ <ulink url="https://fedoraproject.org/wiki/Features/PackagePresets">Features/PackagePresets</ulink>.
+ </para>
</refsect1>
</refentry>
else
split_usr = get_option('split-usr') == 'true'
endif
+if split_usr
+ warning('\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n'
+ + ' split-usr mode is going to be removed\n' +
+ '\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
+endif
conf.set10('HAVE_SPLIT_USR', split_usr,
description : '/usr/bin and /bin directories are separate')
conf.set10('ENABLE_PAM_HOME', have)
have = get_option('oomd')
-if have == 'auto'
- have = get_option('mode') == 'developer'
-else
- have = have == 'true'
- if have and get_option('mode') != 'developer'
- warning('oomd is not ready for release mode (yet)')
- endif
-endif
conf.set10('ENABLE_OOMD', have)
substs.set10('ENABLE_OOMD', have)
conf.get('SYSTEM_ALLOC_UID_MIN')),
'system GIDs: <=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
conf.get('SYSTEM_ALLOC_GID_MIN')),
- 'dynamic UIDs: @0@â\80\93@1@'.format(dynamic_uid_min, dynamic_uid_max),
- 'container UID bases: @0@â\80\93@1@'.format(container_uid_base_min, container_uid_base_max),
+ 'dynamic UIDs: @0@â\80¦@1@'.format(dynamic_uid_min, dynamic_uid_max),
+ 'container UID bases: @0@â\80¦@1@'.format(container_uid_base_min, container_uid_base_max),
'/dev/kvm access mode: @0@'.format(get_option('dev-kvm-mode')),
'render group access mode: @0@'.format(get_option('group-render-mode')),
'certificate root directory: @0@'.format(get_option('certificate-root')),
description : 'install the coredump handler')
option('pstore', type : 'boolean',
description : 'install the pstore archival tool')
-option('oomd', type : 'combo', choices : ['auto', 'true', 'false'],
+option('oomd', type : 'boolean',
description : 'install the userspace oom killer')
option('logind', type : 'boolean',
description : 'install the systemd-logind stack')
--- /dev/null
+#!/bin/sh
+set -e
+
+mkdir -p /root/build
+echo "directory /root/build" > ~/.gdbinit
# Sebastian Rasmussen <sebras@gmail.com>, 2015.
# Andreas Henriksson <andreas@fatal.se>, 2016.
# Josef Andersson <l10nl18nsweja@gmail.com>, 2015, 2017.
-# Göran Uddeborg <goeran@uddeborg.se>, 2020.
+# Göran Uddeborg <goeran@uddeborg.se>, 2020, 2021.
# Luna Jernberg <bittin@reimu.nl>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-01-08 17:48+0100\n"
-"PO-Revision-Date: 2020-12-16 12:36+0000\n"
-"Last-Translator: Luna Jernberg <bittin@reimu.nl>\n"
+"PO-Revision-Date: 2021-02-03 18:40+0000\n"
+"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <https://translate.fedoraproject.org/projects/systemd/"
"master/sv/>\n"
"Language: sv\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.3.2\n"
+"X-Generator: Weblate 4.4.2\n"
#: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system"
#: src/home/org.freedesktop.home1.policy:13
msgid "Create a home area"
-msgstr ""
+msgstr "Skapa en hemarea"
#: src/home/org.freedesktop.home1.policy:14
-#, fuzzy
-#| msgid "Authentication is required to reload the systemd state."
msgid "Authentication is required to create a user's home area."
-msgstr "Autentisering krävs för att läsa om tillståndet för systemd."
+msgstr "Autentisering krävs för att skapa en användares hemarea."
#: src/home/org.freedesktop.home1.policy:23
msgid "Remove a home area"
-msgstr ""
+msgstr "Ta bort en hemarea"
#: src/home/org.freedesktop.home1.policy:24
-#, fuzzy
-#| msgid "Authentication is required to reload the systemd state."
msgid "Authentication is required to remove a user's home area."
-msgstr "Autentisering krävs för att läsa om tillståndet för systemd."
+msgstr "Autentisering krävs för att ta bort en användares hemarea."
#: src/home/org.freedesktop.home1.policy:33
msgid "Check credentials of a home area"
-msgstr ""
+msgstr "Kontrollera kreditiven för en hemarea"
#: src/home/org.freedesktop.home1.policy:34
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to manage active sessions, users and seats."
msgid ""
"Authentication is required to check credentials against a user's home area."
msgstr ""
-"Autentisering krävs för att hantera aktiva sessioner, användare och platser."
+"Autentisering krävs för att kontrollera kreditiven mot en användares hemarea."
#: src/home/org.freedesktop.home1.policy:43
msgid "Update a home area"
-msgstr ""
+msgstr "Uppdatera en hemarea"
#: src/home/org.freedesktop.home1.policy:44
-#, fuzzy
-#| msgid "Authentication is required to attach a device to a seat."
msgid "Authentication is required to update a user's home area."
-msgstr "Autentisering krävs för att binda en enhet till en plats."
+msgstr "Autentisering krävs för att uppdatera en användares hemarea."
#: src/home/org.freedesktop.home1.policy:53
msgid "Resize a home area"
-msgstr ""
+msgstr "Ändra storlek på en hemarea"
#: src/home/org.freedesktop.home1.policy:54
-#, fuzzy
-#| msgid "Authentication is required to set a wall message"
msgid "Authentication is required to resize a user's home area."
-msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
+msgstr "Autentisering krävs för att ändra storlek på en hemarea."
#: src/home/org.freedesktop.home1.policy:63
msgid "Change password of a home area"
-msgstr ""
+msgstr "Ändra lösenord för en hemarea"
#: src/home/org.freedesktop.home1.policy:64
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to manage active sessions, users and seats."
msgid ""
"Authentication is required to change the password of a user's home area."
-msgstr ""
-"Autentisering krävs för att hantera aktiva sessioner, användare och platser."
+msgstr "Autentisering krävs för att ändra lösenorded för en användares hemarea."
#: src/hostname/org.freedesktop.hostname1.policy:20
msgid "Set hostname"
#: src/hostname/org.freedesktop.hostname1.policy:51
msgid "Get product UUID"
-msgstr ""
+msgstr "Hämta produkt-UUID"
#: src/hostname/org.freedesktop.hostname1.policy:52
-#, fuzzy
-#| msgid "Authentication is required to reload '$(unit)'."
msgid "Authentication is required to get product UUID."
-msgstr "Autentisering krävs för att läsa om tillståndet för \"$(unit)\"."
+msgstr "Autentisering krävs för att hämta produkt-UUID."
#: src/import/org.freedesktop.import1.policy:22
msgid "Import a VM or container image"
"av brytaren för datorhöljet."
#: src/login/org.freedesktop.login1.policy:117
-#, fuzzy
-#| msgid "Allow applications to inhibit system handling of the power key"
msgid "Allow applications to inhibit system handling of the reboot key"
-msgstr "Tillåt program att hindra systemhantering av strömknappen"
+msgstr "Tillåt program att hindra systemhantering av omstartsknappen"
#: src/login/org.freedesktop.login1.policy:118
-#, fuzzy
-#| msgid ""
-#| "Authentication is required for an application to inhibit system handling "
-#| "of the power key."
msgid ""
"Authentication is required for an application to inhibit system handling of "
"the reboot key."
msgstr ""
"Autentisering krävs för att tillåta ett program att hindra systemhantering "
-"av strömknappen."
+"av omstartsknappen."
#: src/login/org.freedesktop.login1.policy:128
msgid "Allow non-logged-in user to run programs"
msgstr "Stoppa systemet även då ett program hindrar det"
#: src/login/org.freedesktop.login1.policy:258
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to hibernate the system while an application "
-#| "is inhibiting this."
msgid ""
"Authentication is required to halt the system while an application is "
"inhibiting this."
msgstr ""
-"Autentisering krävs för att försätta ett program i viloläge även då ett "
-"program hindrar det."
+"Autentisering krävs för att stoppa systemet även då ett program hindrar det."
#: src/login/org.freedesktop.login1.policy:268
msgid "Suspend the system"
"Authentication is required to suspend the system while an application is "
"inhibiting this."
msgstr ""
-"Autentisering krävs för att försätta ett program i vänteläge även då ett "
-"program hindrar det."
+"Autentisering krävs för att försätta systemet i sovläge även då ett program "
+"hindrar det."
#: src/login/org.freedesktop.login1.policy:300
msgid "Hibernate the system"
"Authentication is required to hibernate the system while an application is "
"inhibiting this."
msgstr ""
-"Autentisering krävs för att försätta ett program i viloläge även då ett "
-"program hindrar det."
+"Autentisering krävs för att försätta systemet i viloläge även då ett program "
+"hindrar det."
#: src/login/org.freedesktop.login1.policy:332
msgid "Manage active sessions, users and seats"
#: src/login/org.freedesktop.login1.policy:352
msgid "Set the reboot \"reason\" in the kernel"
-msgstr ""
+msgstr "Sätt ”orsaken” för omstart i kärnan"
#: src/login/org.freedesktop.login1.policy:353
-#, fuzzy
-#| msgid "Authentication is required to set the system timezone."
msgid "Authentication is required to set the reboot \"reason\" in the kernel."
-msgstr "Autentisering krävs för att ställa in systemets tidszon."
+msgstr "Autentisering krävs för att ställa in ”orsaken” för omstart i kärnan."
#: src/login/org.freedesktop.login1.policy:363
-#, fuzzy
-#| msgid "Allow indication to the firmware to boot to setup interface"
msgid "Indicate to the firmware to boot to setup interface"
msgstr ""
-"Tillåt indikering till firmware att starta upp i inställningsgränssnitt"
+"Indikera till den fasta programvaran att starta upp i "
+"inställningsgränssnittet"
#: src/login/org.freedesktop.login1.policy:364
msgid ""
#: src/login/org.freedesktop.login1.policy:374
msgid "Indicate to the boot loader to boot to the boot loader menu"
-msgstr ""
+msgstr "Indikera till den startprogrammet att starta upp i uppstartsladdmenyn"
#: src/login/org.freedesktop.login1.policy:375
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to indicate to the firmware to boot to setup "
-#| "interface."
msgid ""
"Authentication is required to indicate to the boot loader to boot to the "
"boot loader menu."
msgstr ""
-"Autentisering krävs för att indikera till firmware att starta upp till "
-"inställningsgränssnitt."
+"Autentisering krävs för att indikera till uppstartsladdaren att starta upp "
+"uppstartsladdmenyn."
#: src/login/org.freedesktop.login1.policy:385
msgid "Indicate to the boot loader to boot a specific entry"
-msgstr ""
+msgstr "Indikera till uppstartsladdaren att starta en specifik post"
#: src/login/org.freedesktop.login1.policy:386
-#, fuzzy
-#| msgid ""
-#| "Authentication is required to indicate to the firmware to boot to setup "
-#| "interface."
msgid ""
"Authentication is required to indicate to the boot loader to boot into a "
"specific boot loader entry."
msgstr ""
-"Autentisering krävs för att indikera till firmware att starta upp till "
-"inställningsgränssnitt."
+"Autentisering krävs för att indikera till uppstartsladdaren att starta upp "
+"till en specifik uppstartsladdspost."
#: src/login/org.freedesktop.login1.policy:396
msgid "Set a wall message"
#: src/login/org.freedesktop.login1.policy:406
msgid "Change Session"
-msgstr ""
+msgstr "Ändra session"
#: src/login/org.freedesktop.login1.policy:407
-#, fuzzy
-#| msgid "Authentication is required to halt the system."
msgid "Authentication is required to change the virtual terminal."
-msgstr "Autentisering krävs för att stoppa systemet."
+msgstr "Autentisering krävs för att ändra den virtuella terminalen."
#: src/machine/org.freedesktop.machine1.policy:22
msgid "Log into a local container"
#: src/network/org.freedesktop.network1.policy:22
msgid "Set NTP servers"
-msgstr ""
+msgstr "Ange NTP-servrar"
#: src/network/org.freedesktop.network1.policy:23
msgid "Authentication is required to set NTP servers."
#: src/network/org.freedesktop.network1.policy:33
#: src/resolve/org.freedesktop.resolve1.policy:44
msgid "Set DNS servers"
-msgstr ""
+msgstr "Ange DNS-servrar"
#: src/network/org.freedesktop.network1.policy:34
#: src/resolve/org.freedesktop.resolve1.policy:45
#: src/network/org.freedesktop.network1.policy:44
#: src/resolve/org.freedesktop.resolve1.policy:55
msgid "Set domains"
-msgstr ""
+msgstr "Ange domäner"
#: src/network/org.freedesktop.network1.policy:45
#: src/resolve/org.freedesktop.resolve1.policy:56
-#, fuzzy
-#| msgid "Authentication is required to stop '$(unit)'."
msgid "Authentication is required to set domains."
-msgstr "Autentisering krävs för att stoppa \"$(unit)\"."
+msgstr "Autentisering krävs för att ange domäner."
#: src/network/org.freedesktop.network1.policy:55
#: src/resolve/org.freedesktop.resolve1.policy:66
msgid "Set default route"
-msgstr ""
+msgstr "Ange standardrutt"
#: src/network/org.freedesktop.network1.policy:56
#: src/resolve/org.freedesktop.resolve1.policy:67
-#, fuzzy
-#| msgid "Authentication is required to set the local hostname."
msgid "Authentication is required to set default route."
-msgstr "Autentisering krävs för att ställa in lokalt värdnamn."
+msgstr "Autentisering krävs för att ange standardrutten."
#: src/network/org.freedesktop.network1.policy:66
#: src/resolve/org.freedesktop.resolve1.policy:77
#: src/network/org.freedesktop.network1.policy:67
#: src/resolve/org.freedesktop.resolve1.policy:78
-#, fuzzy
-#| msgid "Authentication is required to hibernate the system."
msgid "Authentication is required to enable or disable LLMNR."
-msgstr "Autentisering krävs för att försätta systemet i viloläge."
+msgstr "Autentisering krävs för att aktivera eller avaktivera LLMNR."
#: src/network/org.freedesktop.network1.policy:77
#: src/resolve/org.freedesktop.resolve1.policy:88
#: src/network/org.freedesktop.network1.policy:78
#: src/resolve/org.freedesktop.resolve1.policy:89
-#, fuzzy
-#| msgid "Authentication is required to log into the local host."
msgid "Authentication is required to enable or disable multicast DNS."
-msgstr "Autentisering krävs för att logga in på den lokala värden"
+msgstr "Autentisering krävs för att aktivera eller avaktivera multicast-DNS."
#: src/network/org.freedesktop.network1.policy:88
#: src/resolve/org.freedesktop.resolve1.policy:99
#: src/network/org.freedesktop.network1.policy:89
#: src/resolve/org.freedesktop.resolve1.policy:100
-#, fuzzy
-#| msgid "Authentication is required to set the local hostname."
msgid "Authentication is required to enable or disable DNS over TLS."
-msgstr "Autentisering krävs för att ställa in lokalt värdnamn."
+msgstr "Autentisering krävs för att aktivera eller avaktivera DNS över TLS."
#: src/network/org.freedesktop.network1.policy:99
#: src/resolve/org.freedesktop.resolve1.policy:110
#: src/network/org.freedesktop.network1.policy:100
#: src/resolve/org.freedesktop.resolve1.policy:111
-#, fuzzy
-#| msgid "Authentication is required to hibernate the system."
msgid "Authentication is required to enable or disable DNSSEC."
-msgstr "Autentisering krävs för att försätta systemet i viloläge."
+msgstr "Autentisering krävs för att aktivera eller avaktivera DNSSEC."
#: src/network/org.freedesktop.network1.policy:110
#: src/resolve/org.freedesktop.resolve1.policy:121
msgid "Set DNSSEC Negative Trust Anchors"
-msgstr ""
+msgstr "Ange DNSSEC negativa förtroendeankare"
#: src/network/org.freedesktop.network1.policy:111
#: src/resolve/org.freedesktop.resolve1.policy:122
-#, fuzzy
-#| msgid "Authentication is required to set the system locale."
msgid "Authentication is required to set DNSSEC Negative Trust Anchors."
-msgstr "Autentisering krävs för att ställa in systemlokal."
+msgstr "Autentisering krävs för att ange DNSSEC negativa förtroendeankare."
#: src/network/org.freedesktop.network1.policy:121
msgid "Revert NTP settings"
-msgstr ""
+msgstr "Återställ NTP-inställningar"
#: src/network/org.freedesktop.network1.policy:122
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
msgid "Authentication is required to reset NTP settings."
-msgstr "Autentisering krävs för ställa in systemtiden."
+msgstr "Autentisering krävs för återställa NTP-inställningar."
#: src/network/org.freedesktop.network1.policy:132
msgid "Revert DNS settings"
-msgstr ""
+msgstr "Återställ DNS-inställningar"
#: src/network/org.freedesktop.network1.policy:133
-#, fuzzy
-#| msgid "Authentication is required to set the system time."
msgid "Authentication is required to reset DNS settings."
-msgstr "Autentisering krävs för ställa in systemtiden."
+msgstr "Autentisering krävs för att återställa DNS-inställningar."
#: src/network/org.freedesktop.network1.policy:143
msgid "DHCP server sends force renew message"
-msgstr ""
+msgstr "DHCP-servern skickar tvingande förnyelsemeddelande"
#: src/network/org.freedesktop.network1.policy:144
-#, fuzzy
-#| msgid "Authentication is required to set a wall message"
msgid "Authentication is required to send force renew message."
-msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
+msgstr "Autentisering krävs för att skicka tvingande förnyelsemeddelande."
#: src/network/org.freedesktop.network1.policy:154
msgid "Renew dynamic addresses"
-msgstr ""
+msgstr "Förnya dynamiska adresser"
#: src/network/org.freedesktop.network1.policy:155
-#, fuzzy
-#| msgid "Authentication is required to set a wall message"
msgid "Authentication is required to renew dynamic addresses."
-msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
+msgstr "Autentisering krävs för att förnya dynamiska adresser."
#: src/network/org.freedesktop.network1.policy:165
msgid "Reload network settings"
-msgstr ""
+msgstr "Läs om nätverksinställningarna"
#: src/network/org.freedesktop.network1.policy:166
-#, fuzzy
-#| msgid "Authentication is required to reload the systemd state."
msgid "Authentication is required to reload network settings."
-msgstr "Autentisering krävs för att läsa om tillståndet för systemd."
+msgstr "Autentisering krävs för läsa om nätverksinställningarna."
#: src/network/org.freedesktop.network1.policy:176
msgid "Reconfigure network interface"
-msgstr ""
+msgstr "Konfigurera om nätverksgränssnitt"
#: src/network/org.freedesktop.network1.policy:177
-#, fuzzy
-#| msgid "Authentication is required to reboot the system."
msgid "Authentication is required to reconfigure network interface."
-msgstr "Autentisering krävs för att starta om systemet."
+msgstr "Autentisering krävs för att konfigurera om nätverksgränssnitt."
#: src/portable/org.freedesktop.portable1.policy:13
msgid "Inspect a portable service image"
-msgstr ""
+msgstr "Inspektera en portabel tjänsteavbild"
#: src/portable/org.freedesktop.portable1.policy:14
-#, fuzzy
-#| msgid "Authentication is required to import a VM or container image"
msgid "Authentication is required to inspect a portable service image."
-msgstr "Autentisering krävs för att importera en VM eller behållaravbildning"
+msgstr "Autentisering krävs för att inspektera en portabel tjänsteavbild."
#: src/portable/org.freedesktop.portable1.policy:23
msgid "Attach or detach a portable service image"
uid_is_valid(override_uid) ? override_uid : st->st_uid,
gid_is_valid(override_gid) ? override_gid : st->st_gid,
AT_SYMLINK_NOFOLLOW) < 0)
- return -errno;
+ r = -errno;
- return 0;
+ (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
+ return r;
}
/* Encapsulates the database we store potential hardlink targets in */
void *userdata) {
_cleanup_close_ int fdf = -1, fdt = -1;
- struct timespec ts[2];
int r, q;
assert(from);
if (fchmod(fdt, st->st_mode & 07777) < 0)
r = -errno;
- ts[0] = st->st_atim;
- ts[1] = st->st_mtim;
- (void) futimens(fdt, ts);
+ (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
(void) copy_xattr(fdf, fdt);
q = close(fdt);
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
r = -errno;
+ (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
+
(void) memorize_hardlink(hardlink_context, st, dt, to);
return r;
}
if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
r = -errno;
+ (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
+
(void) memorize_hardlink(hardlink_context, st, dt, to);
return r;
}
}
if (created) {
- struct timespec ut[2] = {
- st->st_atim,
- st->st_mtim
- };
-
if (fchown(fdt,
uid_is_valid(override_uid) ? override_uid : st->st_uid,
gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
r = -errno;
(void) copy_xattr(dirfd(d), fdt);
- (void) futimens(fdt, ut);
+ (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
}
return r;
}
int copy_times(int fdf, int fdt, CopyFlags flags) {
- struct timespec ut[2];
struct stat st;
assert(fdf >= 0);
if (fstat(fdf, &st) < 0)
return -errno;
- ut[0] = st.st_atim;
- ut[1] = st.st_mtim;
-
- if (futimens(fdt, ut) < 0)
+ if (futimens(fdt, (struct timespec[2]) { st.st_atim, st.st_mtim }) < 0)
return -errno;
if (FLAGS_SET(flags, COPY_CRTIME)) {
#include <stdbool.h>
#include <unistd.h>
+#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0)
+
+/* For internal use only */
+#define SD_LOGIND_INTERACTIVE (UINT64_C(1) << 63)
+
+#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS)
+#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_INTERACTIVE)
+
bool session_id_valid(const char *id);
static inline bool logind_running(void) {
* Also, the empty string is mapped to itself.
*
* This is different than basename(), which returns "" when a trailing slash is present.
+ *
+ * This always succeeds (except if you pass NULL in which case it returns NULL, too).
*/
unsigned l, k;
int path_extract_filename(const char *p, char **ret) {
_cleanup_free_ char *a = NULL;
- const char *c, *e = NULL, *q;
+ const char *c;
/* Extracts the filename part (i.e. right-most component) from a path, i.e. string that passes
- * filename_is_valid(). A wrapper around last_path_component(), but eats up trailing slashes. */
+ * filename_is_valid(). A wrapper around last_path_component(), but eats up trailing slashes. Returns
+ * -EADDRNOTAVAIL if specified parameter includes no filename (i.e. is "/" or so). Returns -EINVAL if
+ * not a valid path in the first place. */
- if (!p)
+ if (!path_is_valid(p))
return -EINVAL;
- c = last_path_component(p);
+ /* Special case the root dir, because in that case we simply have no filename, but
+ * last_path_component() won't complain */
+ if (path_equal(p, "/"))
+ return -EADDRNOTAVAIL;
- for (q = c; *q != 0; q++)
- if (*q != '/')
- e = q + 1;
-
- if (!e) /* no valid character? */
- return -EINVAL;
+ c = last_path_component(p);
- a = strndup(c, e - c);
+ a = strndup(c, strcspn(c, "/"));
if (!a)
return -ENOMEM;
return -EINVAL;
*ret = TAKE_PTR(a);
-
return 0;
}
if (*e != 0)
return false;
- if (e - p > FILENAME_MAX) /* FILENAME_MAX is counted *without* the trailing NUL byte */
+ if (e - p > NAME_MAX) /* NAME_MAX is counted *without* the trailing NUL byte */
return false;
return true;
if (isempty(p))
return false;
- if (strlen(p) >= PATH_MAX) /* PATH_MAX is counted *with* the trailing NUL byte */
- return false;
+ for (const char *e = p;;) {
+ size_t n;
- return true;
+ /* Skip over slashes */
+ e += strspn(e, "/");
+ if (e - p >= PATH_MAX) /* Already reached the maximum length for a path? (PATH_MAX is counted
+ * *with* the trailing NUL byte) */
+ return false;
+ if (*e == 0) /* End of string? Yay! */
+ return true;
+
+ /* Skip over one component */
+ n = strcspn(e, "/");
+ if (n > NAME_MAX) /* One component larger than NAME_MAX? (NAME_MAX is counted *without* the
+ * trailing NUL byte) */
+ return false;
+
+ e += n;
+ }
}
bool path_is_normalized(const char *p) {
#include "measure.h"
#include "pe.h"
#include "random-seed.h"
+#include "secure-boot.h"
#include "shim.h"
#include "util.h"
/* magic string to find in the binary image */
static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
-static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
-
enum loader_type {
LOADER_UNDEFINED,
LOADER_EFI,
while (!exit) {
EFI_STATUS err;
UINT64 key;
- UINTN i;
+ UINTN j;
- i = len - first;
- if (i >= x_max-1)
- i = x_max-1;
- CopyMem(print, line + first, i * sizeof(CHAR16));
- while (clear > 0 && i < x_max-1) {
+ j = len - first;
+ if (j >= x_max-1)
+ j = x_max-1;
+ CopyMem(print, line + first, j * sizeof(CHAR16));
+ while (clear > 0 && j < x_max-1) {
clear--;
- print[i++] = ' ';
+ print[j++] = ' ';
}
- print[i] = '\0';
+ print[j] = '\0';
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_pos);
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, print);
case KEYPRESS(EFI_ALT_PRESSED, 0, 'd'):
/* kill-word */
clear = 0;
- for (i = first + cursor; i < len && line[i] == ' '; i++)
+
+ UINTN k;
+ for (k = first + cursor; k < len && line[k] == ' '; k++)
clear++;
- for (; i < len && line[i] != ' '; i++)
+ for (; k < len && line[k] != ' '; k++)
clear++;
- for (i = first + cursor; i + clear < len; i++)
+ for (UINTN i = first + cursor; i + clear < len; i++)
line[i] = line[i + clear];
len -= clear;
line[len] = '\0';
}
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos);
- for (i = first + cursor; i + clear < len; i++)
+ for (UINTN i = first + cursor; i + clear < len; i++)
line[i] = line[i + clear];
len -= clear;
line[len] = '\0';
continue;
if (first + cursor == len)
continue;
- for (i = first + cursor; i < len; i++)
+ for (UINTN i = first + cursor; i < len; i++)
line[i] = line[i+1];
clear = 1;
len--;
continue;
if (first == 0 && cursor == 0)
continue;
- for (i = first + cursor-1; i < len; i++)
+ for (UINTN i = first + cursor-1; i < len; i++)
line[i] = line[i+1];
clear = 1;
len--;
case KEYPRESS(0, 0, 0x80) ... KEYPRESS(0, 0, 0xffff):
if (len+1 == size)
continue;
- for (i = len; i > first + cursor; i--)
+ for (UINTN i = len; i > first + cursor; i--)
line[i] = line[i-1];
line[first + cursor] = KEYCHAR(key);
len++;
}
static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
- UINTN i;
-
if (key == 0)
return -1;
/* select entry by number key */
if (key >= '1' && key <= '9') {
- i = key - '0';
+ UINTN i = key - '0';
if (i > config->entry_count)
i = config->entry_count;
return i-1;
}
/* find matching key in config entries */
- for (i = start; i < config->entry_count; i++)
+ for (UINTN i = start; i < config->entry_count; i++)
if (config->entries[i]->key == key)
return i;
- for (i = 0; i < start; i++)
+ for (UINTN i = 0; i < start; i++)
if (config->entries[i]->key == key)
return i;
}
static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
- UINT64 key;
- UINTN i;
- _cleanup_freepool_ CHAR8 *bootvar = NULL, *modevar = NULL, *indvar = NULL;
+ UINT64 key, indvar;
+ UINTN timeout;
+ BOOLEAN modevar;
_cleanup_freepool_ CHAR16 *partstr = NULL, *defaultstr = NULL;
- UINTN x, y, size;
+ UINTN x, y;
uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK);
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
if (uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x, &y) == EFI_SUCCESS)
Print(L"console size: %d x %d\n", x, y);
- if (efivar_get_raw(&global_guid, L"SecureBoot", &bootvar, &size) == EFI_SUCCESS)
- Print(L"SecureBoot: %s\n", yes_no(*bootvar > 0));
+ Print(L"SecureBoot: %s\n", yes_no(secure_boot_enabled()));
- if (efivar_get_raw(&global_guid, L"SetupMode", &modevar, &size) == EFI_SUCCESS)
- Print(L"SetupMode: %s\n", *modevar > 0 ? L"setup" : L"user");
+ if (efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SetupMode", &modevar) == EFI_SUCCESS)
+ Print(L"SetupMode: %s\n", modevar ? L"setup" : L"user");
if (shim_loaded())
Print(L"Shim: present\n");
- if (efivar_get_raw(&global_guid, L"OsIndicationsSupported", &indvar, &size) == EFI_SUCCESS)
- Print(L"OsIndicationsSupported: %d\n", (UINT64)*indvar);
+ if (efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &indvar) == EFI_SUCCESS)
+ Print(L"OsIndicationsSupported: %d\n", indvar);
Print(L"\n--- press key ---\n\n");
console_key_read(&key, TRUE);
Print(L"entry EFI var idx: %d\n", config->idx_default_efivar);
Print(L"\n");
- if (efivar_get_int(L"LoaderConfigTimeout", &i) == EFI_SUCCESS)
- Print(L"LoaderConfigTimeout: %u\n", i);
+ if (efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &timeout) == EFI_SUCCESS)
+ Print(L"LoaderConfigTimeout: %u\n", timeout);
if (config->entry_oneshot)
Print(L"LoaderEntryOneShot: %s\n", config->entry_oneshot);
- if (efivar_get(L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS)
+ if (efivar_get(LOADER_GUID, L"LoaderDevicePartUUID", &partstr) == EFI_SUCCESS)
Print(L"LoaderDevicePartUUID: %s\n", partstr);
- if (efivar_get(L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS)
+ if (efivar_get(LOADER_GUID, L"LoaderEntryDefault", &defaultstr) == EFI_SUCCESS)
Print(L"LoaderEntryDefault: %s\n", defaultstr);
Print(L"\n--- press key ---\n\n");
console_key_read(&key, TRUE);
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
ConfigEntry *entry;
if (key == KEYPRESS(0, SCAN_ESC, 0) || key == KEYPRESS(0, 0, 'q'))
UINTN idx_last;
BOOLEAN refresh;
BOOLEAN highlight;
- UINTN i;
UINTN line_width;
CHAR16 **lines;
UINTN x_start;
/* length of the longest entry */
line_width = 5;
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
UINTN entry_len;
entry_len = StrLen(config->entries[i]->title_show);
/* menu entries title lines */
lines = AllocatePool(sizeof(CHAR16 *) * config->entry_count);
- for (i = 0; i < config->entry_count; i++) {
- UINTN j, k;
+ for (UINTN i = 0; i < config->entry_count; i++) {
+ UINTN j;
lines[i] = AllocatePool(((x_max+1) * sizeof(CHAR16)));
for (j = 0; j < x_start; j++)
lines[i][j] = ' ';
- for (k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++)
+ for (UINTN k = 0; config->entries[i]->title_show[k] != '\0' && j < x_max; j++, k++)
lines[i][j] = config->entries[i]->title_show[k];
for (; j < x_max; j++)
status = NULL;
clearline = AllocatePool((x_max+1) * sizeof(CHAR16));
- for (i = 0; i < x_max; i++)
+ for (UINTN i = 0; i < x_max; i++)
clearline[i] = ' ';
- clearline[i] = 0;
+ clearline[x_max] = 0;
while (!exit) {
UINT64 key;
if (refresh) {
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
if (i < idx_first || i > idx_last)
continue;
uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, 0, y_start + i - idx_first);
case KEYPRESS(0, 0, 'd'):
if (config->idx_default_efivar != (INTN)idx_highlight) {
/* store the selected entry in a persistent EFI variable */
- efivar_set(L"LoaderEntryDefault", config->entries[idx_highlight]->id, TRUE);
+ efivar_set(
+ LOADER_GUID,
+ L"LoaderEntryDefault",
+ config->entries[idx_highlight]->id,
+ TRUE);
config->idx_default_efivar = idx_highlight;
status = StrDuplicate(L"Default boot entry selected.");
} else {
/* clear the default entry EFI variable */
- efivar_set(L"LoaderEntryDefault", NULL, TRUE);
+ efivar_set(LOADER_GUID, L"LoaderEntryDefault", NULL, TRUE);
config->idx_default_efivar = -1;
status = StrDuplicate(L"Default boot entry cleared.");
}
case KEYPRESS(0, 0, 'T'):
if (config->timeout_sec_efivar > 0) {
config->timeout_sec_efivar--;
- efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE);
+ efivar_set_uint_string(
+ LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE);
if (config->timeout_sec_efivar > 0)
status = PoolPrint(L"Menu timeout set to %d sec.", config->timeout_sec_efivar);
else
status = StrDuplicate(L"Menu disabled. Hold down key at bootup to show menu.");
} else if (config->timeout_sec_efivar <= 0){
config->timeout_sec_efivar = -1;
- efivar_set(L"LoaderConfigTimeout", NULL, TRUE);
+ efivar_set(LOADER_GUID, L"LoaderConfigTimeout", NULL, TRUE);
if (config->timeout_sec_config > 0)
status = PoolPrint(L"Menu timeout of %d sec is defined by configuration file.",
config->timeout_sec_config);
if (config->timeout_sec_efivar == -1 && config->timeout_sec_config == 0)
config->timeout_sec_efivar++;
config->timeout_sec_efivar++;
- efivar_set_int(L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE);
+ efivar_set_uint_string(LOADER_GUID, L"LoaderConfigTimeout", config->timeout_sec_efivar, TRUE);
if (config->timeout_sec_efivar > 0)
status = PoolPrint(L"Menu timeout set to %d sec.",
config->timeout_sec_efivar);
*chosen_entry = config->entries[idx_highlight];
- for (i = 0; i < config->entry_count; i++)
+ for (UINTN i = 0; i < config->entry_count; i++)
FreePool(lines[i]);
FreePool(lines);
FreePool(clearline);
/* Let's tell the OS that we renamed this file, so that it knows what to rename to the counter-less name on
* success */
new_path = PoolPrint(L"%s\\%s", entry->path, entry->next_name);
- efivar_set(L"LoaderBootCountPath", new_path, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderBootCountPath", new_path, FALSE);
/* If the file we just renamed is the loader path, then let's update that. */
if (StrCmp(entry->loader, old_path) == 0) {
if (!EFI_ERROR(err))
config_defaults_load_from_file(config, content);
- err = efivar_get_int(L"LoaderConfigTimeout", &sec);
+ err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeout", &sec);
if (!EFI_ERROR(err)) {
config->timeout_sec_efivar = sec > INTN_MAX ? INTN_MAX : sec;
config->timeout_sec = sec;
} else
config->timeout_sec_efivar = -1;
- err = efivar_get_int(L"LoaderConfigTimeoutOneShot", &sec);
+ err = efivar_get_uint_string(LOADER_GUID, L"LoaderConfigTimeoutOneShot", &sec);
if (!EFI_ERROR(err)) {
/* Unset variable now, after all it's "one shot". */
- (void) efivar_set(L"LoaderConfigTimeoutOneShot", NULL, TRUE);
+ (void) efivar_set(LOADER_GUID, L"LoaderConfigTimeoutOneShot", NULL, TRUE);
config->timeout_sec = sec;
config->force_menu = TRUE; /* force the menu when this is set */
UINTN bufsize;
EFI_FILE_INFO *f;
_cleanup_freepool_ CHAR8 *content = NULL;
- UINTN len;
bufsize = sizeof(buf);
err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf);
if (f->Attribute & EFI_FILE_DIRECTORY)
continue;
- len = StrLen(f->FileName);
- if (len < 6)
+ if (!endswith_no_case(f->FileName, L".conf"))
continue;
- if (StriCmp(f->FileName + len - 5, L".conf") != 0)
- continue;
- if (StrnCmp(f->FileName, L"auto-", 5) == 0)
+ if (startswith(f->FileName, L"auto-"))
continue;
err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL);
}
static VOID config_sort_entries(Config *config) {
- UINTN i;
-
- for (i = 1; i < config->entry_count; i++) {
+ for (UINTN i = 1; i < config->entry_count; i++) {
BOOLEAN more;
- UINTN k;
more = FALSE;
- for (k = 0; k < config->entry_count - i; k++) {
+ for (UINTN k = 0; k < config->entry_count - i; k++) {
ConfigEntry *entry;
if (config_entry_compare(config->entries[k], config->entries[k+1]) <= 0)
}
static INTN config_entry_find(Config *config, CHAR16 *id) {
- UINTN i;
-
- for (i = 0; i < config->entry_count; i++)
+ for (UINTN i = 0; i < config->entry_count; i++)
if (StrCmp(config->entries[i]->id, id) == 0)
return (INTN) i;
* The EFI variable to specify a boot entry for the next, and only the
* next reboot. The variable is always cleared directly after it is read.
*/
- err = efivar_get(L"LoaderEntryOneShot", &entry_oneshot);
+ err = efivar_get(LOADER_GUID, L"LoaderEntryOneShot", &entry_oneshot);
if (!EFI_ERROR(err)) {
config->entry_oneshot = StrDuplicate(entry_oneshot);
- efivar_set(L"LoaderEntryOneShot", NULL, TRUE);
+ efivar_set(LOADER_GUID, L"LoaderEntryOneShot", NULL, TRUE);
i = config_entry_find(config, entry_oneshot);
if (i >= 0) {
* the 'd' key in the loader selection menu, the entry is marked with
* an '*'.
*/
- err = efivar_get(L"LoaderEntryDefault", &entry_default);
+ err = efivar_get(LOADER_GUID, L"LoaderEntryDefault", &entry_default);
if (!EFI_ERROR(err)) {
i = config_entry_find(config, entry_default);
static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
BOOLEAN non_unique = FALSE;
- UINTN i, k;
- for (i = 0; i < entry_count; i++)
+ for (UINTN i = 0; i < entry_count; i++)
entries[i]->non_unique = FALSE;
- for (i = 0; i < entry_count; i++)
- for (k = 0; k < entry_count; k++) {
+ for (UINTN i = 0; i < entry_count; i++)
+ for (UINTN k = 0; k < entry_count; k++) {
if (i == k)
continue;
if (StrCmp(entries[i]->title_show, entries[k]->title_show) != 0)
/* generate a unique title, avoiding non-distinguishable menu entries */
static VOID config_title_generate(Config *config) {
- UINTN i;
-
/* set title */
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
CHAR16 *title;
FreePool(config->entries[i]->title_show);
return;
/* add version to non-unique titles */
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
CHAR16 *s;
if (!config->entries[i]->non_unique)
return;
/* add machine-id to non-unique titles */
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
CHAR16 *s;
_cleanup_freepool_ CHAR16 *m = NULL;
return;
/* add file name to non-unique titles */
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
CHAR16 *s;
if (!config->entries[i]->non_unique)
/* look for systemd-boot magic string */
err = file_read(root_dir, loader, 0, 100*1024, &content, &len);
- if (!EFI_ERROR(err)) {
- CHAR8 *start = content;
- CHAR8 *last = content + len - sizeof(magic) - 1;
-
- for (; start <= last; start++)
+ if (!EFI_ERROR(err))
+ for (CHAR8 *start = content; start <= content + len - sizeof(magic) - 1; start++)
if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0)
return FALSE;
- }
}
/* check existence */
err = LibLocateHandle(ByProtocol, &FileSystemProtocol, NULL, &handle_count, &handles);
if (!EFI_ERROR(err)) {
- UINTN i;
-
- for (i = 0; i < handle_count; i++) {
+ for (UINTN i = 0; i < handle_count; i++) {
EFI_FILE *root;
BOOLEAN found;
UINTN szs[ELEMENTSOF(sections)-1] = {};
UINTN addrs[ELEMENTSOF(sections)-1] = {};
CHAR8 *content = NULL;
- UINTN len;
CHAR8 *line;
UINTN pos = 0;
CHAR8 *key, *value;
continue;
if (f->Attribute & EFI_FILE_DIRECTORY)
continue;
- len = StrLen(f->FileName);
- if (len < 5)
+ if (!endswith_no_case(f->FileName, L".efi"))
continue;
- if (StriCmp(f->FileName + len - 4, L".efi") != 0)
- continue;
- if (StrnCmp(f->FileName, L"auto-", 5) == 0)
+ if (startswith(f->FileName, L"auto-"))
continue;
/* look for .osrel and .cmdline sections in the .efi binary */
uefi_call_wrapper(linux_dir->Close, 1, linux_dir);
}
-/* Note that this is in GUID format, i.e. the first 32bit, and the following pair of 16bit are byteswapped. */
-static const UINT8 xbootldr_guid[16] = {
- 0xff, 0xc2, 0x13, 0xbc, 0xe6, 0x59, 0x62, 0x42, 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72
-};
+#define XBOOTLDR_GUID \
+ &(const EFI_GUID) { 0xbc13c2ff, 0x59e6, 0x4262, { 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 } }
static EFI_DEVICE_PATH *path_parent(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node) {
EFI_DEVICE_PATH *parent;
Config *config,
EFI_HANDLE *device) {
- EFI_DEVICE_PATH *partition_path, *node, *disk_path, *copy;
+ EFI_DEVICE_PATH *partition_path, *disk_path, *copy;
UINT32 found_partition_number = (UINT32) -1;
UINT64 found_partition_start = (UINT64) -1;
UINT64 found_partition_size = (UINT64) -1;
if (!partition_path)
return;
- for (node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
+ for (EFI_DEVICE_PATH *node = partition_path; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
EFI_HANDLE disk_handle;
EFI_BLOCK_IO *block_io;
EFI_DEVICE_PATH *p;
- UINTN nr;
/* First, Let's look for the SCSI/SATA/USB/… device path node, i.e. one above the media
* devices */
continue;
/* Try both copies of the GPT header, in case one is corrupted */
- for (nr = 0; nr < 2; nr++) {
+ for (UINTN nr = 0; nr < 2; nr++) {
_cleanup_freepool_ EFI_PARTITION_ENTRY* entries = NULL;
union {
EFI_PARTITION_TABLE_HEADER gpt_header;
} gpt_header_buffer;
const EFI_PARTITION_TABLE_HEADER *h = &gpt_header_buffer.gpt_header;
UINT64 where;
- UINTN i, sz;
+ UINTN sz;
UINT32 c;
if (nr == 0)
if (c != h->PartitionEntryArrayCRC32)
continue;
- for (i = 0; i < h->NumberOfPartitionEntries; i++) {
+ for (UINTN i = 0; i < h->NumberOfPartitionEntries; i++) {
EFI_PARTITION_ENTRY *entry;
entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + h->SizeOfPartitionEntry * i);
- if (CompareMem(&entry->PartitionTypeGUID, xbootldr_guid, 16) == 0) {
+ if (CompareMem(&entry->PartitionTypeGUID, XBOOTLDR_GUID, 16) == 0) {
UINT64 end;
/* Let's use memcpy(), in case the structs are not aligned (they really should be though) */
copy = DuplicateDevicePath(partition_path);
/* Patch in the data we found */
- for (node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
+ for (EFI_DEVICE_PATH *node = copy; !IsDevicePathEnd(node); node = NextDevicePathNode(node)) {
HARDDRIVE_DEVICE_PATH *hd;
if (DevicePathType(node) != MEDIA_DEVICE_PATH)
#endif
}
- efivar_set_time_usec(L"LoaderTimeExecUSec", 0);
+ efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0);
err = uefi_call_wrapper(BS->StartImage, 3, image, NULL, NULL);
out_unload:
uefi_call_wrapper(BS->UnloadImage, 1, image);
}
static EFI_STATUS reboot_into_firmware(VOID) {
- _cleanup_freepool_ CHAR8 *b = NULL;
- UINTN size;
- UINT64 osind;
+ UINT64 old, new;
EFI_STATUS err;
- osind = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
+ new = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
- err = efivar_get_raw(&global_guid, L"OsIndications", &b, &size);
+ err = efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", &old);
if (!EFI_ERROR(err))
- osind |= (UINT64)*b;
+ new |= old;
- err = efivar_set_raw(&global_guid, L"OsIndications", &osind, sizeof(UINT64), TRUE);
+ err = efivar_set_uint64_le(EFI_GLOBAL_GUID, L"OsIndications", new, TRUE);
if (EFI_ERROR(err))
return err;
}
static VOID config_free(Config *config) {
- UINTN i;
-
- for (i = 0; i < config->entry_count; i++)
+ for (UINTN i = 0; i < config->entry_count; i++)
config_entry_free(config->entries[i]);
FreePool(config->entries);
FreePool(config->entry_default_pattern);
static VOID config_write_entries_to_variable(Config *config) {
_cleanup_freepool_ CHAR16 *buffer = NULL;
- UINTN i, sz = 0;
+ UINTN sz = 0;
CHAR16 *p;
- for (i = 0; i < config->entry_count; i++)
+ for (UINTN i = 0; i < config->entry_count; i++)
sz += StrLen(config->entries[i]->id) + 1;
p = buffer = AllocatePool(sz * sizeof(CHAR16));
- for (i = 0; i < config->entry_count; i++) {
+ for (UINTN i = 0; i < config->entry_count; i++) {
UINTN l;
l = StrLen(config->entries[i]->id) + 1;
}
/* Store the full list of discovered entries. */
- (void) efivar_set_raw(&loader_guid, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE);
+ (void) efivar_set_raw(LOADER_GUID, L"LoaderEntries", buffer, (UINT8*) p - (UINT8*) buffer, FALSE);
}
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
0;
_cleanup_freepool_ CHAR16 *infostr = NULL, *typestr = NULL;
- CHAR8 *b;
- UINTN size;
+ UINT64 osind = 0;
EFI_LOADED_IMAGE *loaded_image;
EFI_FILE *root_dir;
CHAR16 *loaded_image_path;
InitializeLib(image, sys_table);
init_usec = time_usec();
- efivar_set_time_usec(L"LoaderTimeInitUSec", init_usec);
- efivar_set(L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE);
+ efivar_set_time_usec(LOADER_GUID, L"LoaderTimeInitUSec", init_usec);
+ efivar_set(LOADER_GUID, L"LoaderInfo", L"systemd-boot " GIT_VERSION, FALSE);
infostr = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
- efivar_set(L"LoaderFirmwareInfo", infostr, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", infostr, FALSE);
typestr = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
- efivar_set(L"LoaderFirmwareType", typestr, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderFirmwareType", typestr, FALSE);
- (void) efivar_set_raw(&loader_guid, L"LoaderFeatures", &loader_features, sizeof(loader_features), FALSE);
+ (void) efivar_set_uint64_le(LOADER_GUID, L"LoaderFeatures", loader_features, FALSE);
err = uefi_call_wrapper(BS->OpenProtocol, 6, image, &LoadedImageProtocol, (VOID **)&loaded_image,
image, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
/* export the device path this image is started from */
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
- efivar_set(L"LoaderDevicePartUUID", uuid, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE);
root_dir = LibOpenRoot(loaded_image->DeviceHandle);
if (!root_dir) {
/* the filesystem path to this image, to prevent adding ourselves to the menu */
loaded_image_path = DevicePathToStr(loaded_image->FilePath);
- efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderImageIdentifier", loaded_image_path, FALSE);
config_load_defaults(&config, root_dir);
L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi");
config_entry_add_osx(&config);
- if (config.auto_firmware && efivar_get_raw(&global_guid, L"OsIndicationsSupported", &b, &size) == EFI_SUCCESS) {
- UINT64 osind = (UINT64)*b;
-
+ if (config.auto_firmware && efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind) == EFI_SUCCESS) {
if (osind & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
config_entry_add_call(&config,
L"auto-reboot-to-firmware-setup",
L"Reboot Into Firmware Interface",
reboot_into_firmware);
- FreePool(b);
}
if (config.entry_count == 0) {
entry = config.entries[config.idx_default];
if (menu) {
- efivar_set_time_usec(L"LoaderTimeMenuUSec", 0);
+ efivar_set_time_usec(LOADER_GUID, L"LoaderTimeMenuUSec", 0);
uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x10000, 0, NULL);
if (!menu_run(&config, &entry, loaded_image_path))
break;
config_entry_bump_counters(entry, root_dir);
/* Export the selected boot entry to the system */
- (VOID) efivar_set(L"LoaderEntrySelected", entry->id, FALSE);
+ (VOID) efivar_set(LOADER_GUID, L"LoaderEntrySelected", entry->id, FALSE);
/* Optionally, read a random seed off the ESP and pass it to the OS */
(VOID) process_random_seed(root_dir, config.random_seed_mode);
#define SYSTEM_FONT_WIDTH 8
#define SYSTEM_FONT_HEIGHT 19
-#define EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \
- { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
+#define EFI_SIMPLE_TEXT_INPUT_EX_GUID \
+ &(EFI_GUID) { 0xdd9e7534, 0x7762, 0x4698, { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } }
struct _EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
} EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL;
EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
- EFI_GUID EfiSimpleTextInputExProtocolGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInputEx;
static BOOLEAN checked;
UINTN index;
EFI_STATUS err;
if (!checked) {
- err = LibLocateProtocol(&EfiSimpleTextInputExProtocolGuid, (VOID **)&TextInputEx);
+ err = LibLocateProtocol(EFI_SIMPLE_TEXT_INPUT_EX_GUID, (VOID **)&TextInputEx);
if (EFI_ERROR(err))
TextInputEx = NULL;
const UINT8 *p = buf;
UINT32 crc = seed;
- UINTN i;
- for (i = 0; i < len; i++) {
+ for (UINTN i = 0; i < len; i++) {
UINT8 x = *p++;
if (i >= exclude_off && i < exclude_off + exclude_len)
device_path = DevicePathFromHandle(handle);
if (device_path) {
_cleanup_freepool_ EFI_DEVICE_PATH *paths = NULL;
- EFI_DEVICE_PATH *path;
paths = UnpackDevicePath(device_path);
- for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) {
+ for (EFI_DEVICE_PATH *path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) {
HARDDRIVE_DEVICE_PATH *drive;
if (DevicePathType(path) != MEDIA_DEVICE_PATH)
#include "graphics.h"
#include "util.h"
+#define EFI_CONSOLE_CONTROL_GUID \
+ &(EFI_GUID) { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } }
+
EFI_STATUS graphics_mode(BOOLEAN on) {
- #define EFI_CONSOLE_CONTROL_PROTOCOL_GUID \
- { 0xf42f7782, 0x12e, 0x4c12, { 0x99, 0x56, 0x49, 0xf9, 0x43, 0x4, 0xf7, 0x21 } };
struct _EFI_CONSOLE_CONTROL_PROTOCOL;
EFI_CONSOLE_CONTROL_PROTOCOL_LOCK_STD_IN LockStdIn;
} EFI_CONSOLE_CONTROL_PROTOCOL;
- EFI_GUID ConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
EFI_CONSOLE_CONTROL_SCREEN_MODE new;
EFI_CONSOLE_CONTROL_SCREEN_MODE current;
BOOLEAN stdin_locked;
EFI_STATUS err;
- err = LibLocateProtocol(&ConsoleControlProtocolGuid, (VOID **)&ConsoleControl);
+ err = LibLocateProtocol(EFI_CONSOLE_CONTROL_GUID, (VOID **)&ConsoleControl);
if (EFI_ERROR(err))
/* console control protocol is nonstandard and might not exist. */
return err == EFI_NOT_FOUND ? EFI_SUCCESS : err;
#include <efi.h>
#include <efilib.h>
+
#include "measure.h"
-#define EFI_TCG_PROTOCOL_GUID { 0xf541796d, 0xa62e, 0x4954, {0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd} }
+#define EFI_TCG_GUID \
+ &(EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
typedef struct _TCG_VERSION {
UINT8 Major;
EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
} EFI_TCG;
-#define EFI_TCG2_PROTOCOL_GUID {0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f }}
+#define EFI_TCG2_GUID \
+ &(EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
}
static EFI_TCG * tcg1_interface_check(void) {
- EFI_GUID tpm_guid = EFI_TCG_PROTOCOL_GUID;
EFI_STATUS status;
EFI_TCG *tcg;
TCG_BOOT_SERVICE_CAPABILITY capability;
EFI_PHYSICAL_ADDRESS event_log_location;
EFI_PHYSICAL_ADDRESS event_log_last_entry;
- status = LibLocateProtocol(&tpm_guid, (void **) &tcg);
+ status = LibLocateProtocol(EFI_TCG_GUID, (void **) &tcg);
if (EFI_ERROR(status))
return NULL;
}
static EFI_TCG2 * tcg2_interface_check(void) {
- EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
EFI_STATUS status;
EFI_TCG2 *tcg;
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
- status = LibLocateProtocol(&tpm2_guid, (void **) &tcg);
+ status = LibLocateProtocol(EFI_TCG2_GUID, (void **) &tcg);
if (EFI_ERROR(status))
return NULL;
graphics.c
measure.c
pe.c
+ secure-boot.c
util.c
'''.split()
if have_gnu_efi
compile_args = ['-Wall',
'-Wextra',
- '-std=gnu90',
- '-nostdinc',
+ '-std=gnu99',
+ '-nostdlib',
'-fpic',
'-fshort-wchar',
'-ffreestanding',
EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs, UINTN *offsets, UINTN *sizes) {
struct DosFileHeader *dos;
struct PeHeader *pe;
- UINTN i;
UINTN offset;
dos = (struct DosFileHeader *)base;
offset = dos->ExeHeader + sizeof(*pe) + pe->FileHeader.SizeOfOptionalHeader;
- for (i = 0; i < pe->FileHeader.NumberOfSections; i++) {
+ for (UINTN i = 0; i < pe->FileHeader.NumberOfSections; i++) {
struct PeSectionHeader *sect;
- UINTN j;
sect = (struct PeSectionHeader *)&base[offset];
- for (j = 0; sections[j]; j++) {
+ for (UINTN j = 0; sections[j]; j++) {
if (CompareMem(sect->Name, sections[j], strlena(sections[j])) != 0)
continue;
#include "missing_efi.h"
#include "random-seed.h"
+#include "secure-boot.h"
#include "sha256.h"
#include "util.h"
-#include "shim.h"
#define RANDOM_MAX_SIZE_MIN (32U)
#define RANDOM_MAX_SIZE_MAX (32U*1024U)
-static const EFI_GUID rng_protocol_guid = EFI_RNG_PROTOCOL_GUID;
+#define EFI_RNG_GUID &(EFI_GUID) EFI_RNG_PROTOCOL_GUID
/* SHA256 gives us 256/8=32 bytes */
#define HASH_VALUE_SIZE 32
/* Try to acquire the specified number of bytes from the UEFI RNG */
- err = LibLocateProtocol((EFI_GUID*) &rng_protocol_guid, (VOID**) &rng);
+ err = LibLocateProtocol(EFI_RNG_GUID, (VOID**) &rng);
if (EFI_ERROR(err))
return err;
if (!rng)
VOID **ret) {
_cleanup_freepool_ VOID *output = NULL;
- UINTN i;
/* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the
* range counter_start…counter_start+n-1. */
if (!output)
return log_oom();
- for (i = 0; i < n; i++)
+ for (UINTN i = 0; i < n; i++)
hash_once(old_seed, rng, size,
system_token, system_token_size,
counter_start + i,
EFI_STATUS err;
UINTN size;
- err = efivar_get_raw(&loader_guid, L"LoaderSystemToken", &data, &size);
+ err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
if (EFI_ERROR(err)) {
if (err != EFI_NOT_FOUND)
Print(L"Failed to read LoaderSystemToken EFI variable: %r", err);
0xaf, 0xac, 0x45, 0x03, 0x7a, 0xfe, 0xe9, 0xd1 }},
};
- UINTN i;
-
- for (i = 0; i < ELEMENTSOF(array); i++) {
+ for (UINTN i = 0; i < ELEMENTSOF(array); i++) {
struct sha256_ctx hash;
uint8_t result[HASH_VALUE_SIZE];
}
/* We are good to go */
- err = efivar_set_raw(&loader_guid, L"LoaderRandomSeed", for_kernel, size, FALSE);
+ err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, FALSE);
if (EFI_ERROR(err)) {
Print(L"Failed to write random seed to EFI variable: %r\n", err);
return err;
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "secure-boot.h"
+#include "util.h"
+
+BOOLEAN secure_boot_enabled(void) {
+ BOOLEAN secure;
+ EFI_STATUS err;
+
+ err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure);
+
+ return !EFI_ERROR(err) && secure;
+}
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <efi.h>
+
+BOOLEAN secure_boot_enabled(void);
void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
/* Take yet unprocessed bytes into account. */
UINT32 bytes = ctx->buflen;
- UINTN pad, i;
+ UINTN pad;
/* Now count remaining bytes. */
ctx->total64 += bytes;
sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
/* Put result from CTX in first 32 bytes following RESBUF. */
- for (i = 0; i < 8; ++i)
+ for (UINTN i = 0; i < 8; ++i)
((UINT32 *) resbuf)[i] = SWAP (ctx->H[i]);
return resbuf;
UINT32 f_save = f;
UINT32 g_save = g;
UINT32 h_save = h;
- UINTN t;
/* Operators defined in FIPS 180-2:4.1.2. */
#define Ch(x, y, z) ((x & y) ^ (~x & z))
#define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
/* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
- for (t = 0; t < 16; ++t) {
+ for (UINTN t = 0; t < 16; ++t) {
W[t] = SWAP (*words);
++words;
}
- for (t = 16; t < 64; ++t)
+ for (UINTN t = 16; t < 64; ++t)
W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
/* The actual computation according to FIPS 180-2:6.2.2 step 3. */
- for (t = 0; t < 64; ++t) {
+ for (UINTN t = 0; t < 64; ++t) {
UINT32 T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
UINT32 T2 = S0 (a) + Maj (a, b, c);
h = g;
EFI_STATUS __sysv_abi__ (*read_header) (VOID *data, UINT32 datasize, VOID *context);
};
-static const EFI_GUID simple_fs_guid = SIMPLE_FILE_SYSTEM_PROTOCOL;
-static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
-
-static const EFI_GUID security_protocol_guid = { 0xa46423e3, 0x4617, 0x49f1, {0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } };
-static const EFI_GUID security2_protocol_guid = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
-static const EFI_GUID shim_lock_guid = { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} };
+#define SIMPLE_FS_GUID &(EFI_GUID) SIMPLE_FILE_SYSTEM_PROTOCOL
+#define SECURITY_PROTOCOL_GUID \
+ &(EFI_GUID) { 0xa46423e3, 0x4617, 0x49f1, { 0xb9, 0xff, 0xd1, 0xbf, 0xa9, 0x11, 0x58, 0x39 } }
+#define SECURITY_PROTOCOL2_GUID \
+ &(EFI_GUID) { 0x94ab2f58, 0x1438, 0x4ef1, { 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } }
+#define SHIM_LOCK_GUID \
+ &(EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
BOOLEAN shim_loaded(void) {
struct ShimLock *shim_lock;
- return uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) == EFI_SUCCESS;
+ return uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) == EFI_SUCCESS;
}
static BOOLEAN shim_validate(VOID *data, UINT32 size) {
if (!data)
return FALSE;
- if (uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &shim_lock_guid, NULL, (VOID**) &shim_lock) != EFI_SUCCESS)
+ if (uefi_call_wrapper(BS->LocateProtocol, 3, SHIM_LOCK_GUID, NULL, (VOID**) &shim_lock) != EFI_SUCCESS)
return FALSE;
if (!shim_lock)
return shim_lock->shim_verify(data, size) == EFI_SUCCESS;
}
-BOOLEAN secure_boot_enabled(void) {
- _cleanup_freepool_ CHAR8 *b = NULL;
- UINTN size;
-
- if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS)
- return *b > 0;
-
- return FALSE;
-}
-
/*
* See the UEFI Platform Initialization manual (Vol2: DXE) for this
*/
dev_path = DuplicateDevicePath((EFI_DEVICE_PATH*) device_path_const);
- status = uefi_call_wrapper(BS->LocateDevicePath, 3, (EFI_GUID*) &simple_fs_guid, &dev_path, &h);
+ status = uefi_call_wrapper(BS->LocateDevicePath, 3, SIMPLE_FS_GUID, &dev_path, &h);
if (status != EFI_SUCCESS)
return status;
* to fail, since SECURITY2 was introduced in PI 1.2.1.
* Use security2_protocol == NULL as indicator.
*/
- uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security2_protocol_guid, NULL, (VOID**) &security2_protocol);
+ uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL2_GUID, NULL, (VOID**) &security2_protocol);
- status = uefi_call_wrapper(BS->LocateProtocol, 3, (EFI_GUID*) &security_protocol_guid, NULL, (VOID**) &security_protocol);
+ status = uefi_call_wrapper(BS->LocateProtocol, 3, SECURITY_PROTOCOL_GUID, NULL, (VOID**) &security_protocol);
/* This one is mandatory, so there's a serious problem */
if (status != EFI_SUCCESS)
return status;
BOOLEAN shim_loaded(void);
-BOOLEAN secure_boot_enabled(void);
-
EFI_STATUS security_policy_install(void);
struct bmp_dib *dib, struct bmp_map *map,
UINT8 *pixmap) {
UINT8 *in;
- UINTN y;
/* transform and copy pixels */
in = pixmap;
- for (y = 0; y < dib->y; y++) {
+ for (UINTN y = 0; y < dib->y; y++) {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *out;
UINTN row_size;
- UINTN x;
out = &buf[(dib->y - y - 1) * dib->x];
- for (x = 0; x < dib->x; x++, in++, out++) {
+ for (UINTN x = 0; x < dib->x; x++, in++, out++) {
switch (dib->depth) {
case 1: {
- UINTN i;
-
- for (i = 0; i < 8 && x < dib->x; i++) {
+ for (UINTN i = 0; i < 8 && x < dib->x; i++) {
out->Red = map[((*in) >> (7 - i)) & 1].red;
out->Green = map[((*in) >> (7 - i)) & 1].green;
out->Blue = map[((*in) >> (7 - i)) & 1].blue;
#include "linux.h"
#include "measure.h"
#include "pe.h"
+#include "secure-boot.h"
#include "splash.h"
#include "util.h"
/* magic string to find in the binary image */
static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub " GIT_VERSION " ####";
-static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
-
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
EFI_LOADED_IMAGE *loaded_image;
- _cleanup_freepool_ CHAR8 *b = NULL;
- UINTN size;
- BOOLEAN secure = FALSE;
CHAR8 *sections[] = {
(CHAR8 *)".cmdline",
(CHAR8 *)".linux",
return err;
}
- if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS)
- if (*b > 0)
- secure = TRUE;
-
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, offs, szs);
if (EFI_ERROR(err)) {
Print(L"Unable to locate embedded .linux section: %r ", err);
}
if (szs[0] > 0)
- cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]);
+ cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
cmdline_len = szs[0];
/* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
- if ((!secure || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 && *(CHAR16 *)loaded_image->LoadOptions > 0x1F) {
+ if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
+ *(CHAR16 *) loaded_image->LoadOptions > 0x1F) {
CHAR16 *options;
CHAR8 *line;
- UINTN i;
options = (CHAR16 *)loaded_image->LoadOptions;
cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8);
line = AllocatePool(cmdline_len);
- for (i = 0; i < cmdline_len; i++)
+ for (UINTN i = 0; i < cmdline_len; i++)
line[i] = options[i];
cmdline = line;
}
/* Export the device path this image is started from, if it's not set yet */
- if (efivar_get_raw(&loader_guid, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS)
+ if (efivar_get_raw(LOADER_GUID, L"LoaderDevicePartUUID", NULL, NULL) != EFI_SUCCESS)
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
- efivar_set(L"LoaderDevicePartUUID", uuid, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderDevicePartUUID", uuid, FALSE);
/* if LoaderImageIdentifier is not set, assume the image with this stub was loaded directly from UEFI */
- if (efivar_get_raw(&loader_guid, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) {
+ if (efivar_get_raw(LOADER_GUID, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS) {
_cleanup_freepool_ CHAR16 *s;
s = DevicePathToStr(loaded_image->FilePath);
- efivar_set(L"LoaderImageIdentifier", s, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderImageIdentifier", s, FALSE);
}
/* if LoaderFirmwareInfo is not set, let's set it */
- if (efivar_get_raw(&loader_guid, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) {
+ if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) {
_cleanup_freepool_ CHAR16 *s;
s = PoolPrint(L"%s %d.%02d", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
- efivar_set(L"LoaderFirmwareInfo", s, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, FALSE);
}
/* ditto for LoaderFirmwareType */
- if (efivar_get_raw(&loader_guid, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) {
+ if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) {
_cleanup_freepool_ CHAR16 *s;
s = PoolPrint(L"UEFI %d.%02d", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
- efivar_set(L"LoaderFirmwareType", s, FALSE);
+ efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, FALSE);
}
/* add StubInfo */
- if (efivar_get_raw(&loader_guid, L"StubInfo", NULL, NULL) != EFI_SUCCESS)
- efivar_set(L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE);
+ if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS)
+ efivar_set(LOADER_GUID, L"StubInfo", L"systemd-stub " GIT_VERSION, FALSE);
if (szs[3] > 0)
graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL);
#include "util.h"
-/*
- * Allocated random UUID, intended to be shared across tools that implement
- * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
- * associated EFI variables.
- */
-const EFI_GUID loader_guid = { 0x4a67b082, 0x0a4c, 0x41cf, {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f} };
-
#ifdef __x86_64__
UINT64 ticks_read(VOID) {
UINT64 a, d;
return uefi_call_wrapper(RT->SetVariable, 5, (CHAR16*) name, (EFI_GUID *)vendor, flags, size, (VOID*) buf);
}
-EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) {
- return efivar_set_raw(&loader_guid, name, value, value ? (StrLen(value)+1) * sizeof(CHAR16) : 0, persistent);
+EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent) {
+ return efivar_set_raw(
+ vendor, name, value, value ? (StrLen(value) + 1) * sizeof(CHAR16) : 0, persistent);
}
-EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent) {
+EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent) {
CHAR16 str[32];
SPrint(str, 32, L"%u", i);
- return efivar_set(name, str, persistent);
+ return efivar_set(vendor, name, str, persistent);
+}
+
+EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *name, UINT32 value, BOOLEAN persistent) {
+ UINT8 buf[4];
+
+ buf[0] = (UINT8)(value >> 0U & 0xFF);
+ buf[1] = (UINT8)(value >> 8U & 0xFF);
+ buf[2] = (UINT8)(value >> 16U & 0xFF);
+ buf[3] = (UINT8)(value >> 24U & 0xFF);
+
+ return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent);
+}
+
+EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent) {
+ UINT8 buf[8];
+
+ buf[0] = (UINT8)(value >> 0U & 0xFF);
+ buf[1] = (UINT8)(value >> 8U & 0xFF);
+ buf[2] = (UINT8)(value >> 16U & 0xFF);
+ buf[3] = (UINT8)(value >> 24U & 0xFF);
+ buf[4] = (UINT8)(value >> 32U & 0xFF);
+ buf[5] = (UINT8)(value >> 40U & 0xFF);
+ buf[6] = (UINT8)(value >> 48U & 0xFF);
+ buf[7] = (UINT8)(value >> 56U & 0xFF);
+
+ return efivar_set_raw(vendor, name, buf, sizeof(buf), persistent);
}
-EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) {
+EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) {
_cleanup_freepool_ CHAR8 *buf = NULL;
EFI_STATUS err;
CHAR16 *val;
UINTN size;
- err = efivar_get_raw(&loader_guid, name, &buf, &size);
+ err = efivar_get_raw(vendor, name, &buf, &size);
if (EFI_ERROR(err))
return err;
return EFI_SUCCESS;
}
-EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i) {
+EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) {
_cleanup_freepool_ CHAR16 *val = NULL;
EFI_STATUS err;
- err = efivar_get(name, &val);
+ err = efivar_get(vendor, name, &val);
if (!EFI_ERROR(err) && i)
*i = Atoi(val);
return err;
}
+EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret) {
+ _cleanup_freepool_ CHAR8 *buf = NULL;
+ UINTN size;
+ EFI_STATUS err;
+
+ err = efivar_get_raw(vendor, name, &buf, &size);
+ if (!EFI_ERROR(err) && ret) {
+ if (size != sizeof(UINT32))
+ return EFI_BUFFER_TOO_SMALL;
+
+ *ret = (UINT32) buf[0] << 0U | (UINT32) buf[1] << 8U | (UINT32) buf[2] << 16U |
+ (UINT32) buf[3] << 24U;
+ }
+
+ return err;
+}
+
+EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret) {
+ _cleanup_freepool_ CHAR8 *buf = NULL;
+ UINTN size;
+ EFI_STATUS err;
+
+ err = efivar_get_raw(vendor, name, &buf, &size);
+ if (!EFI_ERROR(err) && ret) {
+ if (size != sizeof(UINT64))
+ return EFI_BUFFER_TOO_SMALL;
+
+ *ret = (UINT64) buf[0] << 0U | (UINT64) buf[1] << 8U | (UINT64) buf[2] << 16U |
+ (UINT64) buf[3] << 24U | (UINT64) buf[4] << 32U | (UINT64) buf[5] << 40U |
+ (UINT64) buf[6] << 48U | (UINT64) buf[7] << 56U;
+ }
+
+ return err;
+}
+
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size) {
_cleanup_freepool_ CHAR8 *buf = NULL;
UINTN l;
return err;
}
-VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) {
+EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret) {
+ _cleanup_freepool_ CHAR8 *b = NULL;
+ UINTN size;
+ EFI_STATUS err;
+
+ err = efivar_get_raw(vendor, name, &b, &size);
+ if (!EFI_ERROR(err))
+ *ret = *b > 0;
+
+ return err;
+}
+
+VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec) {
CHAR16 str[32];
if (usec == 0)
return;
SPrint(str, 32, L"%ld", usec);
- efivar_set(name, str, FALSE);
+ efivar_set(vendor, name, str, FALSE);
}
static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) {
CHAR16 unichar;
UINTN len;
- UINTN i;
if (!(stra[0] & 0x80))
len = 1;
break;
}
- for (i = 1; i < len; i++) {
+ for (UINTN i = 1; i < len; i++) {
if ((stra[i] & 0xc0) != 0x80)
return -1;
unichar <<= 6;
return NULL;
}
+const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix) {
+ UINTN l;
+
+ l = StrLen(prefix);
+ if (StrnCmp(s, prefix, l) == 0)
+ return s + l;
+
+ return NULL;
+}
+
+const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix) {
+ UINTN sl, pl;
+
+ sl = StrLen(s);
+ pl = StrLen(postfix);
+
+ if (pl == 0)
+ return s + sl;
+
+ if (sl < pl)
+ return NULL;
+
+ if (StrnCmp(s + sl - pl, postfix, pl) != 0)
+ return NULL;
+
+ return s + sl - pl;
+}
+
+const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix) {
+ UINTN l;
+
+ l = StrLen(prefix);
+ if (StriCmp(s, prefix) == 0)
+ return s + l;
+
+ return NULL;
+}
+
+const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix) {
+ UINTN sl, pl;
+
+ sl = StrLen(s);
+ pl = StrLen(postfix);
+
+ if (pl == 0)
+ return s + sl;
+
+ if (sl < pl)
+ return NULL;
+
+ if (StriCmp(s + sl - pl, postfix) != 0)
+ return NULL;
+
+ return s + sl - pl;
+}
+
EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) {
_cleanup_(FileHandleClosep) EFI_FILE_HANDLE handle = NULL;
_cleanup_freepool_ CHAR8 *buf = NULL;
UINT64 ticks_freq(void);
UINT64 time_usec(void);
-EFI_STATUS efivar_set(const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent);
+EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, BOOLEAN persistent);
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID *buf, UINTN size, BOOLEAN persistent);
-EFI_STATUS efivar_set_int(CHAR16 *name, UINTN i, BOOLEAN persistent);
-VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec);
+EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, CHAR16 *name, UINTN i, BOOLEAN persistent);
+EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, CHAR16 *NAME, UINT32 value, BOOLEAN persistent);
+EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, CHAR16 *name, UINT64 value, BOOLEAN persistent);
+VOID efivar_set_time_usec(const EFI_GUID *vendor, CHAR16 *name, UINT64 usec);
-EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value);
+EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value);
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size);
-EFI_STATUS efivar_get_int(const CHAR16 *name, UINTN *i);
+EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i);
+EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret);
+EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret);
+EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret);
CHAR8 *strchra(CHAR8 *s, CHAR8 c);
CHAR16 *stra_to_path(CHAR8 *stra);
CHAR16 *stra_to_str(CHAR8 *stra);
+const CHAR16 *startswith(const CHAR16 *s, const CHAR16 *prefix);
+const CHAR16 *endswith(const CHAR16 *s, const CHAR16 *postfix);
+
+const CHAR16 *startswith_no_case(const CHAR16 *s, const CHAR16 *prefix);
+const CHAR16 *endswith_no_case(const CHAR16 *s, const CHAR16 *postfix);
+
EFI_STATUS file_read(EFI_FILE_HANDLE dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
static inline void FreePoolp(void *p) {
uefi_call_wrapper((*handle)->Close, 1, *handle);
}
-extern const EFI_GUID loader_guid;
+/*
+ * Allocated random UUID, intended to be shared across tools that implement
+ * the (ESP)\loader\entries\<vendor>-<revision>.conf convention and the
+ * associated EFI variables.
+ */
+#define LOADER_GUID \
+ &(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
+#define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE
#define UINTN_MAX (~(UINTN)0)
#define INTN_MAX ((INTN)(UINTN_MAX>>1))
#include "sd-id128.h"
#include "alloc-util.h"
+#include "discover-image.h"
#include "export-raw.h"
#include "export-tar.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "import-util.h"
-#include "machine-image.h"
#include "main-func.h"
#include "signal-util.h"
#include "string-util.h"
#include "alloc-util.h"
#include "btrfs-util.h"
#include "capability-util.h"
+#include "chattr-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "util.h"
int import_make_read_only_fd(int fd) {
+ struct stat st;
int r;
assert(fd >= 0);
/* First, let's make this a read-only subvolume if it refers
* to a subvolume */
r = btrfs_subvol_set_read_only_fd(fd, true);
- if (IN_SET(r, -ENOTTY, -ENOTDIR, -EINVAL)) {
- struct stat st;
+ if (r >= 0)
+ return 0;
- /* This doesn't refer to a subvolume, or the file
- * system isn't even btrfs. In that, case fall back to
- * chmod()ing */
+ if (!ERRNO_IS_NOT_SUPPORTED(r) && !IN_SET(r, -ENOTDIR, -EINVAL))
+ return log_error_errno(r, "Failed to make subvolume read-only: %m");
- r = fstat(fd, &st);
- if (r < 0)
- return log_error_errno(errno, "Failed to stat temporary image: %m");
+ /* This doesn't refer to a subvolume, or the file system isn't even btrfs. In that, case fall back to
+ * chmod()ing */
+
+ r = fstat(fd, &st);
+ if (r < 0)
+ return log_error_errno(errno, "Failed to stat image: %m");
- /* Drop "w" flag */
- if (fchmod(fd, st.st_mode & 07555) < 0)
- return log_error_errno(errno, "Failed to chmod() final image: %m");
+ if (S_ISDIR(st.st_mode)) {
+ /* For directories set the immutable flag on the dir itself */
- return 0;
+ r = chattr_fd(fd, FS_IMMUTABLE_FL, FS_IMMUTABLE_FL, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set +i attribute on directory image: %m");
- } else if (r < 0)
- return log_error_errno(r, "Failed to make subvolume read-only: %m");
+ } else if (S_ISREG(st.st_mode)) {
+ /* For regular files drop "w" flags */
+
+ if ((st.st_mode & 0222) != 0)
+ if (fchmod(fd, st.st_mode & 07555) < 0)
+ return log_error_errno(errno, "Failed to chmod() image: %m");
+ } else
+ return log_error_errno(SYNTHETIC_ERRNO(EBADFD), "Image of unexpected type");
return 0;
}
#include "alloc-util.h"
#include "btrfs-util.h"
+#include "discover-image.h"
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "import-common.h"
#include "import-util.h"
-#include "machine-image.h"
#include "mkdir.h"
#include "ratelimit.h"
#include "rm-rf.h"
#include "sd-id128.h"
#include "alloc-util.h"
+#include "discover-image.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hostname-util.h"
#include "import-raw.h"
#include "import-tar.h"
#include "import-util.h"
-#include "machine-image.h"
#include "main-func.h"
#include "signal-util.h"
#include "string-util.h"
return 0;
}
+static int http_status_ok(CURLcode status) {
+ /* Consider all HTTP status code in the 2xx range as OK */
+ return status >= 200 && status <= 299;
+}
+
+static int http_status_etag_exists(CURLcode status) {
+ /* This one is special, it's triggered by our etag mgmt logic */
+ return status == 304;
+}
+
static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
_cleanup_free_ char *length = NULL, *last_modified = NULL, *etag = NULL;
size_t sz = size * nmemb;
goto fail;
}
- if (status < 200 || status >= 300)
- /* If this is not HTTP 2xx, let's skip these headers, they are probably for
- * some redirect or so, and we are not interested in the headers of those. */
- return sz;
+ if (http_status_ok(status) || http_status_etag_exists(status)) {
+ /* Check Etag on OK and etag exists responses. */
- r = curl_header_strdup(contents, sz, "ETag:", &etag);
- if (r < 0) {
- log_oom();
- goto fail;
- }
- if (r > 0) {
- free_and_replace(j->etag, etag);
+ r = curl_header_strdup(contents, sz, "ETag:", &etag);
+ if (r < 0) {
+ log_oom();
+ goto fail;
+ }
+ if (r > 0) {
+ free_and_replace(j->etag, etag);
+
+ if (strv_contains(j->old_etags, j->etag)) {
+ log_info("Image already downloaded. Skipping download. (%s)", j->etag);
+ j->etag_exists = true;
+ pull_job_finish(j, 0);
+ return sz;
+ }
- if (strv_contains(j->old_etags, j->etag)) {
- log_info("Image already downloaded. Skipping download.");
- j->etag_exists = true;
- pull_job_finish(j, 0);
return sz;
}
+ }
+ if (!http_status_ok(status)) /* Let's ignore the rest here, these requests are probably redirects and
+ * stuff where the headers aren't interesting to us */
return sz;
- }
r = curl_header_strdup(contents, sz, "Content-Length:", &length);
if (r < 0) {
#include "sd-id128.h"
#include "alloc-util.h"
+#include "discover-image.h"
#include "hostname-util.h"
#include "import-util.h"
-#include "machine-image.h"
#include "main-func.h"
#include "parse-util.h"
#include "pull-raw.h"
if want_kernel_install
install_data('kernel-install',
- install_mode : 'rwxr-xr-x',
- install_dir : bindir)
+ install_mode : 'rwxr-xr-x')
install_data('00-entry-directory.install',
'50-depmod.install',
return 0;
}
-int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac,
- uint32_t txqueuelen, uint32_t mtu, uint32_t gso_max_size, size_t gso_max_segments) {
+int rtnl_set_link_properties(
+ sd_netlink **rtnl,
+ int ifindex,
+ const char *alias,
+ const struct ether_addr *mac,
+ uint32_t txqueues,
+ uint32_t rxqueues,
+ uint32_t txqueuelen,
+ uint32_t mtu,
+ uint32_t gso_max_size,
+ size_t gso_max_segments) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
int r;
assert(rtnl);
assert(ifindex > 0);
- if (!alias && !mac && txqueuelen == UINT32_MAX && mtu == 0 && gso_max_size == 0 && gso_max_segments == 0)
+ if (!alias && !mac && txqueues == 0 && rxqueues == 0 && txqueuelen == UINT32_MAX && mtu == 0 &&
+ gso_max_size == 0 && gso_max_segments == 0)
return 0;
if (!*rtnl) {
return r;
}
+ if (txqueues > 0) {
+ r = sd_netlink_message_append_u32(message, IFLA_NUM_TX_QUEUES, txqueues);
+ if (r < 0)
+ return r;
+ }
+
+ if (rxqueues > 0) {
+ r = sd_netlink_message_append_u32(message, IFLA_NUM_RX_QUEUES, rxqueues);
+ if (r < 0)
+ return r;
+ }
+
if (txqueuelen < UINT32_MAX) {
r = sd_netlink_message_append_u32(message, IFLA_TXQLEN, txqueuelen);
if (r < 0)
}
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
-int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac,
- uint32_t txqueuelen, uint32_t mtu, uint32_t gso_max_size, size_t gso_max_segments);
+int rtnl_set_link_properties(
+ sd_netlink **rtnl,
+ int ifindex,
+ const char *alias,
+ const struct ether_addr *mac,
+ uint32_t txqueues,
+ uint32_t rxqueues,
+ uint32_t txqueuelen,
+ uint32_t mtu,
+ uint32_t gso_max_size,
+ size_t gso_max_segments);
int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret);
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names);
return NULL;
if (entry->list) {
- if (entry->list->unique)
+ if (entry->list->unique && entry->name)
hashmap_remove(entry->list->unique_entries, entry->name);
- else
+
+ if (!entry->list->unique || entry->list->uptodate)
LIST_REMOVE(entries, entry->list->entries, entry);
}
struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *_name, const char *_value) {
_cleanup_(udev_list_entry_freep) struct udev_list_entry *entry = NULL;
_cleanup_free_ char *name = NULL, *value = NULL;
- int r;
assert(list);
+ assert(_name);
name = strdup(_name);
if (!name)
return NULL;
*entry = (struct udev_list_entry) {
- .list = list,
.name = TAKE_PTR(name),
.value = TAKE_PTR(value),
};
if (list->unique) {
- r = hashmap_ensure_allocated(&list->unique_entries, &string_hash_ops);
- if (r < 0)
- return NULL;
-
udev_list_entry_free(hashmap_get(list->unique_entries, entry->name));
- r = hashmap_put(list->unique_entries, entry->name, entry);
- if (r < 0)
+ if (hashmap_ensure_put(&list->unique_entries, &string_hash_ops, entry->name, entry) < 0)
return NULL;
list->uptodate = false;
} else
LIST_APPEND(entries, list->entries, entry);
+ entry->list = list;
+
return TAKE_PTR(entry);
}
return;
if (list->unique) {
- hashmap_clear_with_destructor(list->unique_entries, udev_list_entry_free);
list->uptodate = false;
+ hashmap_clear_with_destructor(list->unique_entries, udev_list_entry_free);
} else
LIST_FOREACH_SAFE(entries, i, n, list->entries)
udev_list_entry_free(i);
Manager *m,
sd_bus_message *message,
InhibitWhat w,
- bool interactive,
const char *action,
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
+ uint64_t flags,
sd_bus_error *error) {
_cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
- bool multiple_sessions, blocked;
+ bool multiple_sessions, blocked, interactive;
uid_t uid;
int r;
multiple_sessions = r > 0;
blocked = manager_is_inhibited(m, w, INHIBIT_BLOCK, NULL, false, true, uid, NULL);
+ interactive = flags & SD_LOGIND_INTERACTIVE;
if (multiple_sessions && action_multiple_sessions) {
r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_multiple_sessions, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
}
- if (blocked && action_ignore_inhibit) {
- r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ if (blocked) {
+ /* We don't check polkit for root here, because you can't be more privileged than root */
+ if (uid == 0 && (flags & SD_LOGIND_ROOT_CHECK_INHIBITORS))
+ return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED,
+ "Access denied to root due to active block inhibitor");
+
+ if (action_ignore_inhibit) {
+ r = bus_verify_polkit_async(message, CAP_SYS_BOOT, action_ignore_inhibit, NULL, interactive, UID_INVALID, &m->polkit_registry, error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ }
}
if (!multiple_sessions && !blocked && action) {
const char *action_multiple_sessions,
const char *action_ignore_inhibit,
const char *sleep_verb,
+ bool with_flags,
sd_bus_error *error) {
- int interactive, r;
+ uint64_t flags;
+ int r;
assert(m);
assert(message);
assert(w >= 0);
assert(w <= _INHIBIT_WHAT_MAX);
- r = sd_bus_message_read(message, "b", &interactive);
- if (r < 0)
- return r;
+ if (with_flags) {
+ /* New style method: with flags parameter (and interactive bool in the bus message header) */
+ r = sd_bus_message_read(message, "t", &flags);
+ if (r < 0)
+ return r;
+ if ((flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC) != 0)
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
+ } else {
+ /* Old style method: no flags parameter, but interactive bool passed as boolean in
+ * payload. Let's convert this argument to the new-style flags parameter for our internal
+ * use. */
+ int interactive;
+
+ r = sd_bus_message_read(message, "b", &interactive);
+ if (r < 0)
+ return r;
+
+ flags = interactive ? SD_LOGIND_INTERACTIVE : 0;
+ }
/* Don't allow multiple jobs being executed at the same time */
if (m->action_what > 0)
return r;
}
- r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
- action_ignore_inhibit, error);
+ r = verify_shutdown_creds(m, message, w, action, action_multiple_sessions,
+ action_ignore_inhibit, flags, error);
if (r != 0)
return r;
"org.freedesktop.login1.power-off-multiple-sessions",
"org.freedesktop.login1.power-off-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "PowerOffWithFlags"),
error);
}
"org.freedesktop.login1.reboot-multiple-sessions",
"org.freedesktop.login1.reboot-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"),
error);
}
"org.freedesktop.login1.halt-multiple-sessions",
"org.freedesktop.login1.halt-ignore-inhibit",
NULL,
+ sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"),
error);
}
"org.freedesktop.login1.suspend-multiple-sessions",
"org.freedesktop.login1.suspend-ignore-inhibit",
"suspend",
+ sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"),
error);
}
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hibernate",
+ sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"),
error);
}
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hybrid-sleep",
+ sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"),
error);
}
"org.freedesktop.login1.hibernate-multiple-sessions",
"org.freedesktop.login1.hibernate-ignore-inhibit",
"hybrid-sleep",
+ sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"),
error);
}
} else
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported shutdown type");
- r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, false,
- action, action_multiple_sessions, action_ignore_inhibit, error);
+ r = verify_shutdown_creds(m, message, INHIBIT_SHUTDOWN, action, action_multiple_sessions,
+ action_ignore_inhibit, 0, error);
if (r != 0)
return r;
NULL,,
method_poweroff,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("PowerOffWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_poweroff,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Reboot",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_reboot,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("RebootWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_reboot,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Halt",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_halt,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HaltWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_halt,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Suspend",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_suspend,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SuspendWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_suspend,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Hibernate",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_hibernate,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HibernateWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("HybridSleep",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_hybrid_sleep,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("HybridSleepWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_hybrid_sleep,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernate",
"b",
SD_BUS_PARAM(interactive),
NULL,,
method_suspend_then_hibernate,
SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD_WITH_NAMES("SuspendThenHibernateWithFlags",
+ "t",
+ SD_BUS_PARAM(flags),
+ NULL,,
+ method_suspend_then_hibernate,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("CanPowerOff",
NULL,,
"s",
#include "bus-label.h"
#include "bus-polkit.h"
#include "copy.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "fd-util.h"
#include "fileio.h"
#include "image-dbus.h"
#include "io-util.h"
#include "loop-util.h"
-#include "machine-image.h"
#include "missing_capability.h"
#include "mount-util.h"
#include "process-util.h"
#include "bus-locator.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
+#include "discover-image.h"
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "image-dbus.h"
#include "io-util.h"
#include "machine-dbus.h"
-#include "machine-image.h"
#include "machine-pool.h"
#include "machined.h"
#include "missing_capability.h"
#include "bus-polkit.h"
#include "cgroup-util.h"
#include "dirent-util.h"
+#include "discover-image.h"
#include "fd-util.h"
#include "format-util.h"
#include "hostname-util.h"
#include "label.h"
-#include "machine-image.h"
#include "machined-varlink.h"
#include "machined.h"
#include "main-func.h"
return 0;
}
-static int link_tx_rx_queues_hadler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
- int r;
-
- assert(link);
-
- if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 1;
-
- r = sd_netlink_message_get_errno(m);
- if (r < 0)
- log_link_message_warning_errno(link, m, r, "Could not set transmit / receive queues for the interface");
-
- return 1;
-}
-
-static int link_set_tx_rx_queues(Link *link) {
- _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
- int r;
-
- assert(link);
- assert(link->network);
- assert(link->manager);
- assert(link->manager->rtnl);
-
- if (link->network->txqueues == 0 && link->network->rxqueues == 0)
- return 0;
-
- log_link_debug(link, "Setting transmit / receive queues");
-
- r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
-
- if (link->network->txqueues > 0) {
- r = sd_netlink_message_append_u32(req, IFLA_NUM_TX_QUEUES, link->network->txqueues);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set link transmit queues: %m");
- }
-
- if (link->network->rxqueues > 0) {
- r = sd_netlink_message_append_u32(req, IFLA_NUM_RX_QUEUES, link->network->rxqueues);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set link receive queues: %m");
- }
-
- r = netlink_call_async(link->manager->rtnl, NULL, req, link_tx_rx_queues_hadler,
- link_netlink_destroy_callback, link);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
-
- link_ref(link);
-
- return 0;
-}
-
static int link_handle_bound_to_list(Link *link) {
Link *l;
int r;
if (r < 0)
return r;
- r = link_set_tx_rx_queues(link);
- if (r < 0)
- return r;
-
r = ipv4ll_configure(link);
if (r < 0)
return r;
Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
Link.Group, config_parse_uint32, 0, offsetof(Network, group)
-Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(Network, txqueues)
-Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(Network, rxqueues)
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)
Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
return 0;
}
-int config_parse_rx_tx_queues(
- const char *unit,
- const char *filename,
- unsigned line,
- const char *section,
- unsigned section_line,
- const char *lvalue,
- int ltype,
- const char *rvalue,
- void *data,
- void *userdata) {
-
- uint32_t k, *v = data;
- int r;
-
- if (isempty(rvalue)) {
- *v = 0;
- return 0;
- }
-
- r = safe_atou32(rvalue, &k);
- if (r < 0) {
- log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
- return 0;
- }
- if (k == 0 || k > 4096) {
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
- return 0;
- }
-
- *v = k;
- return 0;
-}
-
DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
"Failed to parse KeepConfiguration= setting");
struct ether_addr *mac;
uint32_t mtu;
uint32_t group;
- uint32_t txqueues;
- uint32_t rxqueues;
int arp;
int multicast;
int allmulticast;
CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
-CONFIG_PARSER_PROTOTYPE(config_parse_rx_tx_queues);
CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
#include "copy.h"
#include "cpu-set-util.h"
#include "dev-setup.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "env-util.h"
#include "escape.h"
#include "log.h"
#include "loop-util.h"
#include "loopback-setup.h"
-#include "machine-image.h"
#include "macro.h"
#include "main-func.h"
#include "missing_sched.h"
#include "copy.h"
#include "def.h"
#include "dirent-util.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
#include "locale-util.h"
#include "loop-util.h"
-#include "machine-image.h"
#include "mkdir.h"
#include "nulstr-util.h"
#include "os-util.h"
#include "bus-wait-for-jobs.h"
#include "def.h"
#include "dirent-util.h"
+#include "discover-image.h"
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
#include "fs-util.h"
#include "locale-util.h"
-#include "machine-image.h"
#include "main-func.h"
#include "pager.h"
#include "parse-util.h"
#include "btrfs-util.h"
#include "bus-common-errors.h"
#include "bus-polkit.h"
+#include "discover-image.h"
#include "fd-util.h"
#include "io-util.h"
-#include "machine-image.h"
#include "missing_capability.h"
#include "portable.h"
#include "portabled-bus.h"
#include "bus-label.h"
#include "bus-polkit.h"
#include "bus-util.h"
+#include "discover-image.h"
#include "fd-util.h"
#include "fileio.h"
#include "io-util.h"
-#include "machine-image.h"
#include "missing_capability.h"
#include "portable.h"
#include "portabled-bus.h"
#include "sd-bus.h"
-#include "machine-image.h"
+#include "discover-image.h"
#include "portabled.h"
int bus_image_common_get_os_release(Manager *m, sd_bus_message *message, const char *name_or_path, Image *image, sd_bus_error *error);
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "discover-image.h"
#include "hashmap.h"
-#include "machine-image.h"
#include "portabled.h"
Image *manager_image_cache_get(Manager *m, const char *name_or_path);
return 0;
}
+static const char *resolve_flags_to_string(uint64_t flags) {
+ return flags & SD_RESOLVED_DNS ? "DNS" :
+ flags & SD_RESOLVED_LLMNR_IPV4 ? "LLMNR/IPv4" :
+ flags & SD_RESOLVED_LLMNR_IPV6 ? "LLMNR/IPv6" :
+ flags & SD_RESOLVED_MDNS_IPV4 ? "mDNS/IPv4" :
+ flags & SD_RESOLVED_MDNS_IPV6 ? "mDNS/IPv6" :
+ "";
+}
+
+static int verb_show_multicast(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(table_unrefp) Table *table = NULL;
+ sd_bus *bus = userdata;
+ int r;
+
+ assert(bus);
+
+ table = table_new("Hostname", "Address", "Source");
+ if (!table)
+ return log_oom();
+
+ r = bus_call_method(bus, bus_resolve_mgr, "GetMulticastHosts", &error, &reply, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query systemd-resolved: %s", bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, 'a', "(stiiay)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ while ((r = sd_bus_message_enter_container(reply, 'r', "stiiay")) > 0) {
+ char *canonical;
+ uint64_t flags;
+ _cleanup_free_ char *pretty = NULL;
+ int ifindex, family;
+ union in_addr_union a;
+
+ r = sd_bus_message_read(reply, "st", &canonical, &flags);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = sd_bus_message_read(reply, "i", &ifindex);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ sd_bus_error_free(&error);
+ r = bus_message_read_in_addr_auto(reply, &error, &family, &a);
+ if (r < 0)
+ return log_error_errno(
+ r,
+ "systemd-resolved returned invalid result: %s",
+ bus_error_message(&error, r));
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = in_addr_ifindex_to_string(family, &a, ifindex, &pretty);
+ if (r < 0)
+ return log_error_errno(r, "Failed to print address: %m");
+
+ r = table_add_many(
+ table,
+ TABLE_STRING,
+ canonical,
+ TABLE_STRING,
+ pretty,
+ TABLE_STRING,
+ resolve_flags_to_string(flags));
+ if (r < 0)
+ return table_log_add_error(r);
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ r = table_print(table, NULL);
+ if (r < 0)
+ return table_log_print_error(r);
+
+ return 0;
+}
+
static void help_protocol_types(void) {
if (arg_legend)
puts("Known protocol types:");
" nta [LINK [DOMAIN...]] Get/set per-interface DNSSEC NTA\n"
" revert LINK Revert per-interface configuration\n"
" log-level [LEVEL] Get/set logging threshold for systemd-resolved\n"
+ " show-multicast Show domain names discovered via LLMNR/mDNS\n"
"\nOptions:\n"
" -h --help Show this help\n"
" --version Show package version\n"
}
static int native_main(int argc, char *argv[], sd_bus *bus) {
-
+ /* clang-format off */
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, verb_help },
{ "status", VERB_ANY, VERB_ANY, VERB_DEFAULT, verb_status },
{ "nta", VERB_ANY, VERB_ANY, 0, verb_nta },
{ "revert", VERB_ANY, 2, 0, verb_revert_link },
{ "log-level", VERB_ANY, 2, 0, verb_log_level },
+ { "show-multicast", VERB_ANY, VERB_ANY, 0, verb_show_multicast },
{}
};
+ /* clang-format on */
return dispatch_verb(argc, argv, verbs, bus);
}
}
}
-static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
+static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex, bool is_container) {
int r;
assert(reply);
assert(rr);
- r = sd_bus_message_open_container(reply, 'r', "iiay");
- if (r < 0)
- return r;
+ if (is_container) {
+ r = sd_bus_message_open_container(reply, 'r', "iiay");
+ if (r < 0)
+ return r;
+ }
r = sd_bus_message_append(reply, "i", ifindex);
if (r < 0)
if (r < 0)
return r;
- r = sd_bus_message_close_container(reply);
- if (r < 0)
- return r;
+ if (is_container) {
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+ }
return 0;
}
if (r == 0)
continue;
- r = append_address(reply, rr, ifindex);
+ r = append_address(reply, rr, ifindex, true);
if (r < 0)
goto finish;
if (r == 0)
continue;
- r = append_address(reply, zz, ifindex);
+ r = append_address(reply, zz, ifindex, true);
if (r < 0)
return r;
}
return call_dnssd_method(m, message, bus_dnssd_method_unregister, error);
}
+static int bus_method_get_multicast_hosts(sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ DnsScope *s;
+ Manager *m = userdata;
+ int r;
+
+ assert(message);
+ assert(m);
+
+ r = sd_bus_message_new_method_return(message, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'a', "(stiiay)");
+ if (r < 0)
+ return r;
+
+ LIST_FOREACH(scopes, s, m->dns_scopes) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ DnsResourceRecord *rr;
+ DnsAnswerFlags flags;
+ int ifindex;
+
+ if (s->protocol == DNS_PROTOCOL_DNS)
+ continue;
+
+ r = dns_cache_dump_to_answer(&s->cache, &answer);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ continue;
+
+ DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, answer) {
+ _cleanup_free_ char *normalized = NULL;
+ bool authenticated = FLAGS_SET(flags, DNS_ANSWER_AUTHENTICATED);
+
+ r = dns_name_normalize(dns_resource_key_name(rr->key), 0, &normalized);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(reply, 'r', "stiiay");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(
+ reply,
+ "st",
+ normalized,
+ SD_RESOLVED_FLAGS_MAKE(s->protocol, s->family, authenticated));
+ if (r < 0)
+ return r;
+
+ r = append_address(reply, rr, ifindex, false);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ r = sd_bus_message_close_container(reply);
+ if (r < 0)
+ return r;
+
+ return sd_bus_reply(message, reply);
+}
+
+/* clang-format off */
static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_NO_RESULT,
bus_method_reset_server_features,
SD_BUS_VTABLE_UNPRIVILEGED),
-
+ SD_BUS_METHOD_WITH_ARGS("GetMulticastHosts",
+ SD_BUS_NO_ARGS,
+ SD_BUS_RESULT("a(stiiay)", addresses),
+ bus_method_get_multicast_hosts,
+ SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
+/* clang-format on */
const BusObjectImplementation manager_object = {
"/org/freedesktop/resolve1",
return 0;
}
-void dns_cache_dump(DnsCache *cache, FILE *f) {
+int dns_cache_dump_to_answer(DnsCache *cache, DnsAnswer **ret) {
+ _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
+ DnsCacheItem *i;
+ size_t n = 0;
+ int r;
+
+ assert(cache);
+ assert(ret);
+
+ HASHMAP_FOREACH(i, cache->by_key) {
+ DnsCacheItem *j;
+
+ LIST_FOREACH(by_key, j, i) {
+ if (!j->rr)
+ continue;
+
+ n++;
+ }
+ }
+
+ if (n == 0) {
+ *ret = NULL;
+ return 0;
+ }
+
+ answer = dns_answer_new(n);
+ if (!answer)
+ return -ENOMEM;
+
+ HASHMAP_FOREACH(i, cache->by_key) {
+ DnsCacheItem *j;
+
+ LIST_FOREACH(by_key, j, i) {
+ if (!j->rr)
+ continue;
+
+ r = dns_answer_add(
+ answer, j->rr, j->ifindex, j->authenticated ? DNS_ANSWER_AUTHENTICATED : 0);
+ if (r < 0)
+ return r;
+ }
+ }
+
+ *ret = TAKE_PTR(answer);
+
+ return n;
+}
+
+void dns_cache_dump_to_file(DnsCache *cache, FILE *f) {
DnsCacheItem *i;
if (!cache)
int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_family, const union in_addr_union *owner_address);
-void dns_cache_dump(DnsCache *cache, FILE *f);
+void dns_cache_dump_to_file(DnsCache *cache, FILE *f);
+int dns_cache_dump_to_answer(DnsCache *cache, DnsAnswer **answer);
bool dns_cache_is_empty(DnsCache *cache);
unsigned dns_cache_size(DnsCache *cache);
if (!dns_cache_is_empty(&s->cache)) {
fputs("CACHE:\n", f);
- dns_cache_dump(&s->cache, f);
+ dns_cache_dump_to_file(&s->cache, f);
}
}
#include "chattr-util.h"
#include "copy.h"
#include "dirent-util.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "env-file.h"
#include "env-util.h"
#include "lockfile-util.h"
#include "log.h"
#include "loop-util.h"
-#include "machine-image.h"
#include "macro.h"
#include "mkdir.h"
#include "nulstr-util.h"
r = asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino);
else
return -ENOTTY;
-
if (r < 0)
return -ENOMEM;
}
}
int image_name_lock(const char *name, int operation, LockFile *ret) {
+ const char *p;
+
assert(name);
assert(ret);
/* Locks an image name, regardless of the precise path used. */
+ if (streq(name, ".host"))
+ return -EBUSY;
+
if (!image_name_is_valid(name))
return -EINVAL;
return 0;
}
- if (streq(name, ".host"))
- return -EBUSY;
-
- const char *p = strjoina("/run/systemd/nspawn/locks/name-", name);
(void) mkdir_p("/run/systemd/nspawn/locks", 0700);
+
+ p = strjoina("/run/systemd/nspawn/locks/name-", name);
return make_lock_file(p, operation, ret);
}
dev-setup.c
dev-setup.h
devnode-acl.h
+ discover-image.c
+ discover-image.h
dissect-image.c
dissect-image.h
dm-util.c
loopback-setup.h
machine-id-setup.c
machine-id-setup.h
- machine-image.c
- machine-image.h
machine-pool.c
machine-pool.h
macvlan-util.c
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "alloc-util.h"
+#include "discover-image.h"
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "macro.h"
-#include "machine-image.h"
#include "os-util.h"
#include "string-util.h"
#include "strv.h"
#include <unistd.h>
#include "capability-util.h"
+#include "discover-image.h"
#include "dissect-image.h"
#include "escape.h"
#include "fd-util.h"
#include "fs-util.h"
#include "hashmap.h"
#include "log.h"
-#include "machine-image.h"
#include "main-func.h"
#include "missing_magic.h"
#include "mkdir.h"
#include "bus-error.h"
#include "bus-locator.h"
+#include "login-util.h"
#include "process-util.h"
#include "systemctl-logind.h"
#include "systemctl-start-unit.h"
};
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ const char *method_with_flags;
+ uint64_t flags = 0;
sd_bus *bus;
int r;
if (arg_dry_run)
return 0;
+ SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0);
+
+ method_with_flags = strjoina(actions[a].method, "WithFlags");
+
+ r = bus_call_method(bus, bus_login_mgr, method_with_flags, &error, NULL, "t", flags);
+ if (r >= 0)
+ return 0;
+ if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
+ return log_error_errno(r, "Failed to %s via logind: %s", actions[a].description, bus_error_message(&error, r));
+
+ /* Fallback to original methods in case there is older version of systemd-logind */
+ log_debug("Method %s not available: %s. Falling back to %s", method_with_flags, bus_error_message(&error, r), actions[a].method);
+ sd_bus_error_free(&error);
+
r = bus_call_method(bus, bus_login_mgr, actions[a].method, &error, NULL, "b", arg_ask_password);
if (r < 0)
return log_error_errno(r, "Failed to %s via logind: %s", actions[a].description, bus_error_message(&error, r));
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);
int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state);
int sd_rtnl_message_neigh_get_family(const sd_netlink_message *m, int *family);
-int sd_rtnl_message_neigh_get_ifindex(const sd_netlink_message *m, int *family);
+int sd_rtnl_message_neigh_get_ifindex(const sd_netlink_message *m, int *index);
int sd_rtnl_message_neigh_get_state(const sd_netlink_message *m, uint16_t *state);
int sd_rtnl_message_neigh_get_flags(const sd_netlink_message *m, uint8_t *flags);
test_path_extract_filename_one(NULL, NULL, -EINVAL);
test_path_extract_filename_one("a/b/c", "c", 0);
test_path_extract_filename_one("a/b/c/", "c", 0);
- test_path_extract_filename_one("/", NULL, -EINVAL);
- test_path_extract_filename_one("//", NULL, -EINVAL);
- test_path_extract_filename_one("///", NULL, -EINVAL);
+ test_path_extract_filename_one("/", NULL, -EADDRNOTAVAIL);
+ test_path_extract_filename_one("//", NULL, -EADDRNOTAVAIL);
+ test_path_extract_filename_one("///", NULL, -EADDRNOTAVAIL);
test_path_extract_filename_one(".", NULL, -EINVAL);
test_path_extract_filename_one("./.", NULL, -EINVAL);
test_path_extract_filename_one("././", NULL, -EINVAL);
}
static void test_filename_is_valid(void) {
- char foo[FILENAME_MAX+2];
- int i;
+ char foo[NAME_MAX+2];
log_info("/* %s */", __func__);
assert_se(!filename_is_valid("bar/foo/"));
assert_se(!filename_is_valid("bar//"));
- for (i=0; i<FILENAME_MAX+1; i++)
- foo[i] = 'a';
- foo[FILENAME_MAX+1] = '\0';
+ memset(foo, 'a', sizeof(foo) - 1);
+ char_array_0(foo);
assert_se(!filename_is_valid(foo));
assert_se(filename_is_valid("o.o"));
}
+static void test_path_is_valid(void) {
+ char foo[PATH_MAX+2];
+ const char *c;
+
+ log_info("/* %s */", __func__);
+
+ assert_se(!path_is_valid(""));
+ assert_se(path_is_valid("/bar/foo"));
+ assert_se(path_is_valid("/bar/foo/"));
+ assert_se(path_is_valid("/bar/foo/"));
+ assert_se(path_is_valid("//bar//foo//"));
+ assert_se(path_is_valid("/"));
+ assert_se(path_is_valid("/////"));
+ assert_se(path_is_valid("/////.///.////...///..//."));
+ assert_se(path_is_valid("."));
+ assert_se(path_is_valid(".."));
+ assert_se(path_is_valid("bar/foo"));
+ assert_se(path_is_valid("bar/foo/"));
+ assert_se(path_is_valid("bar//"));
+
+ memset(foo, 'a', sizeof(foo) -1);
+ char_array_0(foo);
+
+ assert_se(!path_is_valid(foo));
+
+ c = strjoina("/xxx/", foo, "/yyy");
+ assert_se(!path_is_valid(c));
+
+ assert_se(path_is_valid("foo_bar-333"));
+ assert_se(path_is_valid("o.o"));
+}
+
static void test_hidden_or_backup_file(void) {
log_info("/* %s */", __func__);
test_last_path_component();
test_path_extract_filename();
test_filename_is_valid();
+ test_path_is_valid();
test_hidden_or_backup_file();
test_skip_dev_prefix();
test_empty_or_root();
#include "condition.h"
#include "device-private.h"
#include "device.h"
+#include "discover-image.h"
#include "execute.h"
#include "import-util.h"
#include "install.h"
#include "locale-util.h"
#include "log.h"
#include "logs-show.h"
-#include "machine-image.h"
#include "mount.h"
#include "path.h"
#include "process-util.h"
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(link_config, alternative_names)
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(link_config, alternative_names_policy)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
-Link.TxQueueLength, config_parse_txqueuelen, 0, offsetof(link_config, txqueuelen)
+Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(link_config, txqueues)
+Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(link_config, rxqueues)
+Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(link_config, txqueuelen)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(link_config, speed)
Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
} else
mac = config->mac;
- r = rtnl_set_link_properties(rtnl, ifindex, config->alias, mac, config->txqueuelen, config->mtu,
- config->gso_max_size, config->gso_max_segments);
+ r = rtnl_set_link_properties(rtnl, ifindex, config->alias, mac,
+ config->txqueues, config->rxqueues, config->txqueuelen,
+ config->mtu, config->gso_max_size, config->gso_max_segments);
if (r < 0)
- log_device_warning_errno(device, r, "Could not set Alias=, MACAddress=, TxQueueLength=, MTU=, "
- "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, ignoring: %m");
+ log_device_warning_errno(device, r,
+ "Could not set Alias=, MACAddress=, "
+ "TransmitQueues=, ReceiveQueues=, TransmitQueueLength=, MTU=, "
+ "GenericSegmentOffloadMaxBytes= or GenericSegmentOffloadMaxSegments=, "
+ "ignoring: %m");
return 0;
}
return 0;
}
+int config_parse_rx_tx_queues(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ uint32_t k, *v = data;
+ int r;
+
+ if (isempty(rvalue)) {
+ *v = 0;
+ return 0;
+ }
+
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s.", lvalue, rvalue);
+ return 0;
+ }
+ if (k == 0 || k > 4096) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s=, ignoring assignment: %s.", lvalue, rvalue);
+ return 0;
+ }
+
+ *v = k;
+ return 0;
+}
+
int config_parse_txqueuelen(
const char *unit,
const char *filename,
char *name;
char **alternative_names;
char *alias;
+ uint32_t txqueues;
+ uint32_t rxqueues;
uint32_t txqueuelen;
uint32_t mtu;
uint32_t gso_max_segments;
const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
CONFIG_PARSER_PROTOTYPE(config_parse_ifalias);
+CONFIG_PARSER_PROTOTYPE(config_parse_rx_tx_queues);
CONFIG_PARSER_PROTOTYPE(config_parse_txqueuelen);
CONFIG_PARSER_PROTOTYPE(config_parse_mac_address_policy);
CONFIG_PARSER_PROTOTYPE(config_parse_name_policy);
AlternativeNamesPolicy=
AlternativeName=
Alias=
-TxQueueLength=
+TransmitQueues=
+ReceiveQueues=
+TransmitQueueLength=
MTUBytes=
BitsPerSecond=
Duplex=
MACAddress=
Group=
Promiscuous=
-TransmitQueues=
-ReceiveQueues=
[SR-IOV]
VirtualFunction=
MACSpoofCheck=
Name=veth-peer
[Network]
+IPv6AcceptRA=no
IPv6SendRA=yes
[IPv6SendRA]