]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18444 from anitazha/proprename
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 4 Feb 2021 11:53:10 +0000 (12:53 +0100)
committerGitHub <noreply@github.com>
Thu, 4 Feb 2021 11:53:10 +0000 (12:53 +0100)
oom: parse properties with 1/10000 precision instead of 1/100

80 files changed:
.packit.yml
README
docs/PORTABILITY_AND_STABILITY.md
man/org.freedesktop.login1.xml
man/org.freedesktop.resolve1.xml
man/resolvectl.xml
man/systemctl.xml
man/systemd.link.xml
man/systemd.network.xml
man/systemd.preset.xml
meson.build
meson_options.txt
mkosi.postinst [new file with mode: 0755]
po/sv.po
src/basic/copy.c
src/basic/login-util.h
src/basic/path-util.c
src/boot/efi/boot.c
src/boot/efi/console.c
src/boot/efi/crc32.c
src/boot/efi/disk.c
src/boot/efi/graphics.c
src/boot/efi/measure.c
src/boot/efi/meson.build
src/boot/efi/pe.c
src/boot/efi/random-seed.c
src/boot/efi/secure-boot.c [new file with mode: 0644]
src/boot/efi/secure-boot.h [new file with mode: 0644]
src/boot/efi/sha256.c
src/boot/efi/shim.c
src/boot/efi/shim.h
src/boot/efi/splash.c
src/boot/efi/stub.c
src/boot/efi/util.c
src/boot/efi/util.h
src/import/export.c
src/import/import-common.c
src/import/import-fs.c
src/import/import.c
src/import/pull-job.c
src/import/pull.c
src/kernel-install/meson.build
src/libsystemd/sd-netlink/netlink-util.c
src/libsystemd/sd-netlink/netlink-util.h
src/libudev/libudev-list.c
src/login/logind-dbus.c
src/machine/image-dbus.c
src/machine/machined-dbus.c
src/machine/machined.c
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/nspawn/nspawn.c
src/portable/portable.c
src/portable/portablectl.c
src/portable/portabled-bus.c
src/portable/portabled-image-bus.c
src/portable/portabled-image-bus.h
src/portable/portabled-image.h
src/resolve/resolvectl.c
src/resolve/resolved-bus.c
src/resolve/resolved-dns-cache.c
src/resolve/resolved-dns-cache.h
src/resolve/resolved-dns-scope.c
src/shared/discover-image.c [moved from src/shared/machine-image.c with 99% similarity]
src/shared/discover-image.h [moved from src/shared/machine-image.h with 100% similarity]
src/shared/meson.build
src/shared/os-util.c
src/sysext/sysext.c
src/systemctl/systemctl-logind.c
src/systemd/sd-netlink.h
src/test/test-path-util.c
src/test/test-tables.c
src/udev/net/link-config-gperf.gperf
src/udev/net/link-config.c
src/udev/net/link-config.h
test/fuzz/fuzz-link-parser/directives.link
test/fuzz/fuzz-network-parser/directives.network
test/test-network/conf/ipv6-prefix.network

index 0c3c17b9da96e25a0c7f0e05b41a2321d3ef5ff2..e1ace861ddc4cdd78c7c22a3f88ce3e568f9a331 100644 (file)
@@ -22,8 +22,18 @@ actions:
     # - 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
diff --git a/README b/README
index 1617c3d195f5aa0e85ff6fc896fefa7aefd11ca8..032477bcbf671f8dbe4dcdde7cc5bb9515996ec0 100644 (file)
--- a/README
+++ b/README
@@ -219,9 +219,10 @@ REQUIREMENTS:
         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)
index 0caa5cc04846c47618b595e279a3b25c502772ab..27562c17d8f6689ddd7942b65dd7fa7b57dab652 100644 (file)
@@ -120,7 +120,7 @@ And now, here's the list of (hopefully) all APIs that we have introduced with sy
 | `/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 |
 
 
index ad27b226b8ab2c8b8010ee3a94de42231dd1bcde..bf7a5fa3402d843958cb35c82b2a2835106b85bd 100644 (file)
@@ -102,12 +102,19 @@ node /org/freedesktop/login1 {
                    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);
@@ -291,18 +298,32 @@ node /org/freedesktop/login1 {
 
     <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()"/>
@@ -525,8 +546,19 @@ node /org/freedesktop/login1 {
       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) &lt;&lt; 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
index 860a14877d19bf89ba2e83de4f7f633164d187a9..9036f7d11fd4be5e3d76ecf56c9348c8bd63116b 100644 (file)
@@ -115,6 +115,7 @@ node /org/freedesktop/resolve1 {
       ResetStatistics();
       FlushCaches();
       ResetServerFeatures();
+      GetMulticastHosts(out a(stiiay) UNNAMED);
     properties:
       readonly s LLMNRHostname = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
@@ -164,6 +165,8 @@ node /org/freedesktop/resolve1 {
 
     <!--method ResetServerFeatures is not documented!-->
 
+    <!--method GetMulticastHosts is not documented!-->
+
     <!--property DNSSECNegativeTrustAnchors is not documented!-->
 
     <!--Autogenerated cross-references for systemd.directives, do not edit-->
@@ -212,6 +215,8 @@ node /org/freedesktop/resolve1 {
 
     <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"/>
index fb6cae7b9b6a6bd447c3afdfe02381ddbacaf6d3..c6e9f147a7a1a40e1bd2b0ab8c00e53797f4c1be 100644 (file)
         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>
index e49a12a146e9e3eba57878ddd94456d0422206b8..db4e2b2c65c551d37990cf53ac888e569d087ef5 100644 (file)
@@ -793,9 +793,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
 
             <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>
 
index 0b7055bf591a948401b30626d1f848332ca7506b..93f7191b3321109aad8f875d0280e3fb9d8abce9 100644 (file)
         </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>
index 8e7b190638ab06a3d5a6b75c0e70c23b20680442..606a2dd5dbbf637f9b3a7af9e13616c25fffdfda 100644 (file)
           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>
index 5697e50be7c6de411eb298d203cb1c4b27033957..cbd89daf1629db10438f6fb39d64a27d6c2466db 100644 (file)
   <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
@@ -175,6 +167,38 @@ disable *</programlisting>
     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>
@@ -182,6 +206,13 @@ disable *</programlisting>
       <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>
index 0af0cce8b85827da7ae89d9d8f3257a80f048afd..62b11aba2df388335f5ee49a0798239a717cf2ae 100644 (file)
@@ -68,6 +68,11 @@ if get_option('split-usr') == 'auto'
 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')
 
@@ -1450,14 +1455,6 @@ have = have and conf.get('HAVE_PAM') == 1
 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)
 
@@ -3668,8 +3665,8 @@ status = [
                                                                         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')),
index a42147302997a7943bc7f0f77e7701e3c728451e..425e958ba20af3f6d783fd64752a7e87ff91350e 100644 (file)
@@ -99,7 +99,7 @@ option('coredump', type : 'boolean',
        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')
diff --git a/mkosi.postinst b/mkosi.postinst
new file mode 100755 (executable)
index 0000000..1bbb9e4
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+set -e
+
+mkdir -p /root/build
+echo "directory /root/build" > ~/.gdbinit
index 116e3e1098d5db04152b1879c86219a1fbc5be34..f2dd3839c97ca73b844d3913928c3e1f87bc84ba 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -4,15 +4,15 @@
 # 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"
@@ -20,7 +20,7 @@ msgstr ""
 "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"
@@ -72,69 +72,54 @@ msgstr "Autentisering krävs för att läsa om tillståndet för systemd."
 
 #: 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"
@@ -166,13 +151,11 @@ msgstr "Autentisering krävs för att ställa in lokal datorinformation."
 
 #: 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"
@@ -316,22 +299,16 @@ msgstr ""
 "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"
@@ -457,16 +434,11 @@ msgid "Halt the system while an application is inhibiting this"
 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"
@@ -497,8 +469,8 @@ msgid ""
 "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"
@@ -529,8 +501,8 @@ msgid ""
 "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"
@@ -551,20 +523,17 @@ msgstr "Autentisering krävs för att låsa eller låsa upp aktiva sessioner."
 
 #: 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 ""
@@ -576,35 +545,27 @@ msgstr ""
 
 #: 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"
@@ -616,13 +577,11 @@ msgstr "Autentisering krävs för att ställa in ett väggmeddelande"
 
 #: 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"
@@ -701,7 +660,7 @@ msgstr ""
 
 #: 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."
@@ -710,7 +669,7 @@ msgstr "Autentisering krävs för ställa in NTP-servrar."
 #: 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
@@ -720,26 +679,22 @@ msgstr "Autentisering krävs för ställa in DNS-servrar."
 #: 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
@@ -748,10 +703,8 @@ msgstr "Aktivera/inaktivera LLMNR"
 
 #: 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
@@ -760,10 +713,8 @@ msgstr "Aktivera/inaktivera multicast-DNS"
 
 #: 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
@@ -772,10 +723,8 @@ msgstr "Aktivera/inaktivera DNS över TLS"
 
 #: 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
@@ -784,92 +733,74 @@ msgstr "Aktivera/inaktivera DNSSEC"
 
 #: 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"
index aa805bb8e25acbf9e5303b37e453251dcd5a9cfc..aede5be9910d9957f4bd8e22314ca236de45155f 100644 (file)
@@ -391,9 +391,10 @@ static int fd_copy_symlink(
                      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 */
@@ -592,7 +593,6 @@ static int fd_copy_regular(
                 void *userdata) {
 
         _cleanup_close_ int fdf = -1, fdt = -1;
-        struct timespec ts[2];
         int r, q;
 
         assert(from);
@@ -634,9 +634,7 @@ static int fd_copy_regular(
         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);
@@ -693,6 +691,8 @@ static int fd_copy_fifo(
         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;
 }
@@ -739,6 +739,8 @@ static int fd_copy_node(
         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;
 }
@@ -913,11 +915,6 @@ static int fd_copy_directory(
         }
 
         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)
@@ -927,7 +924,7 @@ static int fd_copy_directory(
                         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;
@@ -1182,7 +1179,6 @@ int copy_file_atomic_full(
 }
 
 int copy_times(int fdf, int fdt, CopyFlags flags) {
-        struct timespec ut[2];
         struct stat st;
 
         assert(fdf >= 0);
@@ -1191,10 +1187,7 @@ int copy_times(int fdf, int fdt, CopyFlags flags) {
         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)) {
index 00a124dc9fbdcbc80ffbcf3724383fcc1e368122..dff87697a64c0dd830a67f08d3eaacdd10c755a3 100644 (file)
@@ -4,6 +4,14 @@
 #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) {
index 5bcbc7a7947278058c274b6b757cc7c34740aba9..f7498d012568538681e51cb60435232270b1d608 100644 (file)
@@ -823,6 +823,8 @@ const char *last_path_component(const char *path) {
          *    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;
@@ -848,24 +850,24 @@ const char *last_path_component(const char *path) {
 
 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;
 
@@ -873,7 +875,6 @@ int path_extract_filename(const char *p, char **ret) {
                 return -EINVAL;
 
         *ret = TAKE_PTR(a);
-
         return 0;
 }
 
@@ -890,7 +891,7 @@ bool filename_is_valid(const char *p) {
         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;
@@ -901,10 +902,25 @@ bool path_is_valid(const char *p) {
         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) {
index e1a7dd1f32ee9c9bf2b6e8a3d642e7106d635c51..c88a6db9deee71df6a12d500c1b9a943cb11224a 100644 (file)
@@ -13,6 +13,7 @@
 #include "measure.h"
 #include "pe.h"
 #include "random-seed.h"
+#include "secure-boot.h"
 #include "shim.h"
 #include "util.h"
 
@@ -23,8 +24,6 @@
 /* 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,
@@ -119,17 +118,17 @@ static BOOLEAN line_edit(
         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);
@@ -213,12 +212,14 @@ static BOOLEAN line_edit(
                 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';
@@ -243,7 +244,7 @@ static BOOLEAN line_edit(
                         }
                         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';
@@ -256,7 +257,7 @@ static BOOLEAN line_edit(
                                 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--;
@@ -285,7 +286,7 @@ static BOOLEAN line_edit(
                                 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--;
@@ -313,7 +314,7 @@ static BOOLEAN line_edit(
                 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++;
@@ -331,25 +332,23 @@ static BOOLEAN line_edit(
 }
 
 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;
 
@@ -357,11 +356,11 @@ static UINTN entry_lookup_key(Config *config, UINTN start, CHAR16 key) {
 }
 
 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);
@@ -376,17 +375,16 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
         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);
@@ -423,20 +421,20 @@ static VOID print_status(Config *config, CHAR16 *loaded_image_path) {
                 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'))
@@ -503,7 +501,6 @@ static BOOLEAN menu_run(
         UINTN idx_last;
         BOOLEAN refresh;
         BOOLEAN highlight;
-        UINTN i;
         UINTN line_width;
         CHAR16 **lines;
         UINTN x_start;
@@ -564,7 +561,7 @@ static BOOLEAN menu_run(
 
         /* 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);
@@ -583,14 +580,14 @@ static BOOLEAN menu_run(
 
         /* 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++)
@@ -600,15 +597,15 @@ static BOOLEAN menu_run(
 
         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);
@@ -764,12 +761,16 @@ static BOOLEAN menu_run(
                 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.");
                         }
@@ -780,14 +781,15 @@ static BOOLEAN menu_run(
                 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);
@@ -801,7 +803,7 @@ static BOOLEAN menu_run(
                         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);
@@ -863,7 +865,7 @@ static BOOLEAN menu_run(
 
         *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);
@@ -1293,7 +1295,7 @@ static VOID config_entry_bump_counters(
         /* 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) {
@@ -1458,17 +1460,17 @@ static VOID config_load_defaults(Config *config, EFI_FILE *root_dir) {
         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 */
@@ -1491,7 +1493,6 @@ static VOID config_load_entries(
                         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);
@@ -1504,12 +1505,9 @@ static VOID config_load_entries(
                         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);
@@ -1553,14 +1551,11 @@ static INTN config_entry_compare(ConfigEntry *a, ConfigEntry *b) {
 }
 
 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)
@@ -1577,9 +1572,7 @@ static VOID config_sort_entries(Config *config) {
 }
 
 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;
 
@@ -1595,11 +1588,11 @@ static VOID config_default_entry_select(Config *config) {
          * 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) {
@@ -1614,7 +1607,7 @@ static VOID config_default_entry_select(Config *config) {
          * 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);
@@ -1660,13 +1653,12 @@ static VOID config_default_entry_select(Config *config) {
 
 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)
@@ -1680,10 +1672,8 @@ static BOOLEAN find_nonunique(ConfigEntry **entries, UINTN entry_count) {
 
 /* 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);
@@ -1697,7 +1687,7 @@ static VOID config_title_generate(Config *config) {
                 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)
@@ -1714,7 +1704,7 @@ static VOID config_title_generate(Config *config) {
                 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;
 
@@ -1734,7 +1724,7 @@ static VOID config_title_generate(Config *config) {
                 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)
@@ -1826,14 +1816,10 @@ static BOOLEAN config_entry_add_loader_auto(
 
                 /* 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 */
@@ -1862,9 +1848,7 @@ static VOID config_entry_add_osx(Config *config) {
 
         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;
 
@@ -1906,7 +1890,6 @@ static VOID config_entry_add_linux(
                 UINTN szs[ELEMENTSOF(sections)-1] = {};
                 UINTN addrs[ELEMENTSOF(sections)-1] = {};
                 CHAR8 *content = NULL;
-                UINTN len;
                 CHAR8 *line;
                 UINTN pos = 0;
                 CHAR8 *key, *value;
@@ -1926,12 +1909,9 @@ static VOID config_entry_add_linux(
                         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 */
@@ -2020,10 +2000,8 @@ static VOID config_entry_add_linux(
         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;
@@ -2041,7 +2019,7 @@ static VOID config_load_xbootldr(
                 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;
@@ -2054,11 +2032,10 @@ static VOID config_load_xbootldr(
         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 */
@@ -2085,7 +2062,7 @@ static VOID config_load_xbootldr(
                         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;
@@ -2093,7 +2070,7 @@ static VOID config_load_xbootldr(
                         } 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)
@@ -2163,12 +2140,12 @@ static VOID config_load_xbootldr(
                         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) */
@@ -2197,7 +2174,7 @@ found:
         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)
@@ -2282,7 +2259,7 @@ static EFI_STATUS image_start(
 #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);
@@ -2290,18 +2267,16 @@ out_unload:
 }
 
 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;
 
@@ -2312,9 +2287,7 @@ static EFI_STATUS reboot_into_firmware(VOID) {
 }
 
 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);
@@ -2324,15 +2297,15 @@ static VOID config_free(Config *config) {
 
 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;
@@ -2342,7 +2315,7 @@ static VOID config_write_entries_to_variable(Config *config) {
         }
 
         /* 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) {
@@ -2357,8 +2330,7 @@ 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;
@@ -2370,16 +2342,16 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
         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);
@@ -2391,7 +2363,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
         /* 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) {
@@ -2411,7 +2383,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
         /* 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);
 
@@ -2436,15 +2408,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                                      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) {
@@ -2497,7 +2466,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
 
                 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;
@@ -2512,7 +2481,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 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);
index 2dd4543d515df6cce1c8217831c811f9b462c871..e3de27fee5cc4e598dbdfc814280126371a49641 100644 (file)
@@ -9,8 +9,8 @@
 #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;
 
@@ -67,7 +67,6 @@ typedef 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;
@@ -75,7 +74,7 @@ EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait) {
         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;
 
index 5dfd3db265f7f03fbc500bfa96bd60004414200f..c9e5501ffa7c4f42c1c1c508c4bfabc26cc4b321 100644 (file)
@@ -128,9 +128,8 @@ UINT32 crc32_exclude_offset(
 
         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)
index cc752956c3489ac3f7e2844828b4963cb61af6fb..122f08dd5cd151308322e7c96bea1fe1fb2c005f 100644 (file)
@@ -13,10 +13,9 @@ EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) {
         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)
index f36ecb35b5b37f1e884e216a72329e3eebc3afa9..ddfe68cc77454494e9a4e042c45cf92b871bbaf4 100644 (file)
 #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;
 
@@ -45,7 +46,6 @@ EFI_STATUS graphics_mode(BOOLEAN on) {
                 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;
@@ -53,7 +53,7 @@ EFI_STATUS graphics_mode(BOOLEAN on) {
         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;
index ff876a6c5b30e70585c5e402ecf8170b695d6ae0..c272d0855379753ea5039abfab9d3777a3e885ab 100644 (file)
@@ -4,9 +4,11 @@
 
 #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;
@@ -100,7 +102,8 @@ typedef struct _EFI_TCG {
         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;
 
@@ -238,7 +241,6 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32
 }
 
 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;
@@ -246,7 +248,7 @@ static EFI_TCG * tcg1_interface_check(void) {
         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;
@@ -267,12 +269,11 @@ static EFI_TCG * tcg1_interface_check(void) {
 }
 
 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;
index 24177f938408d28b0ffb5e7fe6ea2da6a0c7da22..177957e76ac66c7883b79f7c81793c7f73c48868 100644 (file)
@@ -21,6 +21,7 @@ common_sources = '''
         graphics.c
         measure.c
         pe.c
+        secure-boot.c
         util.c
 '''.split()
 
@@ -133,8 +134,8 @@ endif
 if have_gnu_efi
         compile_args = ['-Wall',
                         '-Wextra',
-                        '-std=gnu90',
-                        '-nostdinc',
+                        '-std=gnu99',
+                        '-nostdlib',
                         '-fpic',
                         '-fshort-wchar',
                         '-ffreestanding',
index f99ecd0eda07555f462cadefc15e017d7d52ec0b..cb3583807211d9fce7c0954e39aa9bd9a94a41dc 100644 (file)
@@ -62,7 +62,6 @@ struct PeSectionHeader {
 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;
@@ -85,12 +84,11 @@ EFI_STATUS pe_memory_locate_sections(CHAR8 *base, CHAR8 **sections, UINTN *addrs
 
         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;
 
index 895c85445ef010af4325a059f0c6b6ee13ba24df..cd4025260787398e7f82752c03486bcc38dec1dc 100644 (file)
@@ -5,14 +5,14 @@
 
 #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
@@ -24,7 +24,7 @@ static EFI_STATUS acquire_rng(UINTN size, VOID **ret) {
 
         /* 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)
@@ -86,7 +86,6 @@ static EFI_STATUS hash_many(
                 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. */
@@ -95,7 +94,7 @@ static EFI_STATUS hash_many(
         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,
@@ -147,7 +146,7 @@ static EFI_STATUS acquire_system_token(VOID **ret, UINTN *ret_size) {
         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);
@@ -201,9 +200,7 @@ static VOID validate_sha256(void) {
                     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];
 
@@ -318,7 +315,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
         }
 
         /* 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;
diff --git a/src/boot/efi/secure-boot.c b/src/boot/efi/secure-boot.c
new file mode 100644 (file)
index 0000000..cacf3b6
--- /dev/null
@@ -0,0 +1,13 @@
+/* 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;
+}
diff --git a/src/boot/efi/secure-boot.h b/src/boot/efi/secure-boot.h
new file mode 100644 (file)
index 0000000..d06a7de
--- /dev/null
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <efi.h>
+
+BOOLEAN secure_boot_enabled(void);
index f23066d0acff34376cd144c74db5a5fbd08a3add..774f0eeb6c0e658495c40d7e4ad4bd7bbb4e485f 100644 (file)
@@ -94,7 +94,7 @@ void sha256_init_ctx(struct sha256_ctx *ctx) {
 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;
@@ -111,7 +111,7 @@ void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
         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;
@@ -214,7 +214,6 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct
                 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))
@@ -229,15 +228,15 @@ static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ct
 #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;
index 3dc10089c6c02a74b82cf67e071c49e8bd377929..48602627bb7eda8e7e6ce5a6e460812a5e5ab74b 100644 (file)
@@ -30,17 +30,18 @@ struct ShimLock {
         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) {
@@ -49,7 +50,7 @@ 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)
@@ -58,16 +59,6 @@ static BOOLEAN shim_validate(VOID *data, UINT32 size) {
         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
  */
@@ -157,7 +148,7 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
 
         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;
 
@@ -191,9 +182,9 @@ EFI_STATUS security_policy_install(void) {
          * 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;
index e24fcdac540bef423f9e95d930216f869589f456..d682994b9e50445e7f4eda1cedb6b52ad5509197 100644 (file)
@@ -13,6 +13,4 @@
 
 BOOLEAN shim_loaded(void);
 
-BOOLEAN secure_boot_enabled(void);
-
 EFI_STATUS security_policy_install(void);
index 552c45cff49a1176aacd910f23586bb97f953807..5e085ec45c2289fb5fd03f5f4327e5e02221b7f2 100644 (file)
@@ -151,22 +151,18 @@ static EFI_STATUS bmp_to_blt(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf,
                       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;
index a09f47c71194600d4b0a87b767b78bc1bf816d2a..0bef6b1c44f8b001d800ef079223f1b78805388e 100644 (file)
@@ -8,19 +8,15 @@
 #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",
@@ -46,10 +42,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 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);
@@ -58,20 +50,20 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         }
 
         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;
 
@@ -88,37 +80,37 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         }
 
         /* 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);
index 2712c2d3f0eb081f231a307f87bfb8828eb62eb2..8adf3f5fe45741f8d48a33319b09247e73c98964 100644 (file)
@@ -5,13 +5,6 @@
 
 #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;
@@ -92,24 +85,51 @@ EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const VOID
         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;
 
@@ -138,17 +158,52 @@ EFI_STATUS efivar_get(const CHAR16 *name, CHAR16 **value) {
         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;
@@ -172,7 +227,19 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu
         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)
@@ -181,13 +248,12 @@ VOID efivar_set_time_usec(CHAR16 *name, UINT64 usec) {
                 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;
@@ -225,7 +291,7 @@ static INTN utf8_to_16(CHAR8 *stra, CHAR16 *c) {
                 break;
         }
 
-        for (i = 1; i < len; i++) {
+        for (UINTN i = 1; i < len; i++) {
                 if ((stra[i] & 0xc0) != 0x80)
                         return -1;
                 unichar <<= 6;
@@ -309,6 +375,62 @@ CHAR8 *strchra(CHAR8 *s, CHAR8 c) {
         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;
index 916519cdf83ae82dbf0adbf3e1a102f99fb9e751..f2be857d427b6a2c324e0657a091d6edad210164 100644 (file)
@@ -21,19 +21,30 @@ UINT64 ticks_read(void);
 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) {
@@ -55,7 +66,14 @@ static inline void FileHandleClosep(EFI_FILE_HANDLE *handle) {
         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))
index 9c44fcf35cc746e19dd1dfeba31332f9a02eff73..5faf4ccc06b0516577f752c776369b59c22e72e5 100644 (file)
@@ -7,13 +7,13 @@
 #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"
index bbe0ba719cd7bb8adac4f882c9f4f29ad17ab8e9..f77564c41dc53f8fa8ca5cf3270083f42a37639c 100644 (file)
@@ -8,6 +8,7 @@
 #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"
@@ -22,6 +23,7 @@
 #include "util.h"
 
 int import_make_read_only_fd(int fd) {
+        struct stat st;
         int r;
 
         assert(fd >= 0);
@@ -29,25 +31,34 @@ int import_make_read_only_fd(int fd) {
         /* 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;
 }
index 1fe5a257dbd66b720b2b86b1e4a31494e719b000..a12ee77ef9fc7fb6bdc85ad9d15ed85d7449b4a3 100644 (file)
@@ -5,13 +5,13 @@
 
 #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"
index 934074a7b0abd22eba5d7611732bd96449106c53..661fa2888c58b41f5f1b39b9cf29cbb49b15b4b0 100644 (file)
@@ -7,13 +7,13 @@
 #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"
index d1e61ba601f0e964e6798b467c4c70810331c452..908546b96839af76e449a2c58ee38b5f4ec2e7b1 100644 (file)
@@ -433,6 +433,16 @@ fail:
         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;
@@ -458,28 +468,31 @@ static size_t pull_job_header_callback(void *contents, size_t size, size_t 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) {
index a54f968cd76eb2c8934f66408e1931487de0d501..dc0bf20201daec125f2b57f49b80ce2ee204138e 100644 (file)
@@ -7,9 +7,9 @@
 #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"
index 4117188f147463913050a1a465e815b9316d076a..92ce23ecf91628e3830350e16b88aa6693e117ff 100644 (file)
@@ -4,8 +4,7 @@ want_kernel_install = get_option('kernel-install')
 
 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',
index a0bc44e7fbbf14503098d50dede031d5dc5d78e3..448c50d4ab44e0b9e5c2124ae6eecc5f04d4df60 100644 (file)
@@ -57,15 +57,25 @@ int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
         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) {
@@ -90,6 +100,18 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
                         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)
index acf5b668a293fbcb83ecde6b7a4d66f7418d3ef7..a3a3951ff7942e79908b0899aeb9cfec55da07a1 100644 (file)
@@ -70,8 +70,17 @@ static inline bool rtnl_message_type_is_mdb(uint16_t type) {
 }
 
 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);
index 3b2a2cdee4b3337db0ec543f14fa09d90b073388..69efc1013c1e724336486391c34bce20ee4803b0 100644 (file)
@@ -39,9 +39,10 @@ static struct udev_list_entry *udev_list_entry_free(struct udev_list_entry *entr
                 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);
         }
 
@@ -70,9 +71,9 @@ struct udev_list *udev_list_new(bool unique) {
 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)
@@ -89,26 +90,22 @@ struct udev_list_entry *udev_list_entry_add(struct udev_list *list, const char *
                 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);
 }
 
@@ -119,8 +116,8 @@ void udev_list_cleanup(struct udev_list *list) {
                 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);
index b95af1a9fd6508df32bc135aa2fe8d3ecc4b1b68..7e55173e27e6f01204222b360c35c2075755a090 100644 (file)
@@ -1793,14 +1793,14 @@ static int verify_shutdown_creds(
                 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;
 
@@ -1823,6 +1823,7 @@ static int verify_shutdown_creds(
 
         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);
@@ -1832,12 +1833,19 @@ static int verify_shutdown_creds(
                         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) {
@@ -1860,9 +1868,11 @@ static int method_do_shutdown_or_sleep(
                 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);
@@ -1870,9 +1880,25 @@ static int method_do_shutdown_or_sleep(
         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)
@@ -1891,8 +1917,8 @@ static int method_do_shutdown_or_sleep(
                         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;
 
@@ -1914,6 +1940,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error
                         "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);
 }
 
@@ -1928,6 +1955,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *
                         "org.freedesktop.login1.reboot-multiple-sessions",
                         "org.freedesktop.login1.reboot-ignore-inhibit",
                         NULL,
+                        sd_bus_message_is_method_call(message, NULL, "RebootWithFlags"),
                         error);
 }
 
@@ -1942,6 +1970,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er
                         "org.freedesktop.login1.halt-multiple-sessions",
                         "org.freedesktop.login1.halt-ignore-inhibit",
                         NULL,
+                        sd_bus_message_is_method_call(message, NULL, "HaltWithFlags"),
                         error);
 }
 
@@ -1956,6 +1985,7 @@ static int method_suspend(sd_bus_message *message, void *userdata, sd_bus_error
                         "org.freedesktop.login1.suspend-multiple-sessions",
                         "org.freedesktop.login1.suspend-ignore-inhibit",
                         "suspend",
+                        sd_bus_message_is_method_call(message, NULL, "SuspendWithFlags"),
                         error);
 }
 
@@ -1970,6 +2000,7 @@ static int method_hibernate(sd_bus_message *message, void *userdata, sd_bus_erro
                         "org.freedesktop.login1.hibernate-multiple-sessions",
                         "org.freedesktop.login1.hibernate-ignore-inhibit",
                         "hibernate",
+                        sd_bus_message_is_method_call(message, NULL, "HibernateWithFlags"),
                         error);
 }
 
@@ -1984,6 +2015,7 @@ static int method_hybrid_sleep(sd_bus_message *message, void *userdata, sd_bus_e
                         "org.freedesktop.login1.hibernate-multiple-sessions",
                         "org.freedesktop.login1.hibernate-ignore-inhibit",
                         "hybrid-sleep",
+                        sd_bus_message_is_method_call(message, NULL, "HybridSleepWithFlags"),
                         error);
 }
 
@@ -1998,6 +2030,7 @@ static int method_suspend_then_hibernate(sd_bus_message *message, void *userdata
                         "org.freedesktop.login1.hibernate-multiple-sessions",
                         "org.freedesktop.login1.hibernate-ignore-inhibit",
                         "hybrid-sleep",
+                        sd_bus_message_is_method_call(message, NULL, "SuspendThenHibernateWithFlags"),
                         error);
 }
 
@@ -2185,8 +2218,8 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_
         } 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;
 
@@ -3538,42 +3571,84 @@ static const sd_bus_vtable manager_vtable[] = {
                                  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",
index f74cabd7fb753a85ae4d1bdf247f9d73a0eeb7de..539b4c802a62e640c5f60d1c6207cb5198f179f5 100644 (file)
@@ -8,6 +8,7 @@
 #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"
@@ -15,7 +16,6 @@
 #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"
index a65f9b6a8e5628ea604504fd30c966ae2dfb6c07..08179eb4006cc277b01ad9155e09bd50d8f38490 100644 (file)
@@ -12,6 +12,7 @@
 #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"
@@ -20,7 +21,6 @@
 #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"
index 6a5bf391e6b24d477d302c215315e697210a3157..1d820599858298194af13d206e1f19ebe66ddc11 100644 (file)
 #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"
index fe6d3bd927c87832f3ab27b50a97e05b4956669d..ccefb46cbc60974eeaf5b8790379cbbda9f14398 100644 (file)
@@ -1479,61 +1479,6 @@ static int link_set_group(Link *link) {
         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;
@@ -2111,10 +2056,6 @@ int link_configure(Link *link) {
         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;
index f1344c0fcc6ed2cd5a3aab291d94f7c84aa9e748..7f0de7660c31a040dd54dff2c240f02fe35bde84 100644 (file)
@@ -60,8 +60,6 @@ Match.Architecture,                          config_parse_net_condition,
 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)
index 62e3ff0cc623dd9cbec113392c769e76197dae67..84ab1d5e18d673981ddcef3c7b7fc150ad293874 100644 (file)
@@ -1198,40 +1198,6 @@ int config_parse_required_for_online(
         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");
 
index b1db17f7b72be444594b24c634cb71c32c1c2ff5..baa806fca6cbc2f26c3a7c02cd4bf073b761eb45 100644 (file)
@@ -95,8 +95,6 @@ struct Network {
         struct ether_addr *mac;
         uint32_t mtu;
         uint32_t group;
-        uint32_t txqueues;
-        uint32_t rxqueues;
         int arp;
         int multicast;
         int allmulticast;
@@ -344,7 +342,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
 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);
index aa3bcdb7a299ab50444e08f23a289481c3a60106..a702af8e3bd95af2b08d58cec04acce997e060c4 100644 (file)
@@ -36,6 +36,7 @@
 #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"
@@ -53,7 +54,6 @@
 #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"
index d74e498d596d67f19e7a5c29eca892a6b0b75ee7..d18e03afd4fd1adf20cd94e196bc0ba788269c78 100644 (file)
@@ -8,6 +8,7 @@
 #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"
@@ -16,7 +17,6 @@
 #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"
index 0b329134de5926ca64206b1c18e72babef97f08c..ee1c7b696510f2844369f8e45570006509ab2d24 100644 (file)
 #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"
index cf50d58c71dff5da8e53b9b805456ace19920d05..20a33dc6716c0931a11b19208389cf5ccad68f59 100644 (file)
@@ -4,9 +4,9 @@
 #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"
index 76b6ddebde374068beb41508f0b79ffd67e79abf..babdf4197fa51383d6d333ba0bfff2bc997b6a1d 100644 (file)
 #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"
index aa2a3ade7706723c1f4edb6f6e0460026ed73ab0..8442baf232c0753c7ea0e62750bc7f71890c47a0 100644 (file)
@@ -3,7 +3,7 @@
 
 #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);
index eeefffee64e3180d214bdd8d45e1b0db9cfcaa2b..753f389f80d24df8a6181748ba54cd99709a7086 100644 (file)
@@ -1,8 +1,8 @@
 /* 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);
index b1779a6418a43c8a8865f9688893dcde69ab1be8..77b7b72ed9b8affe7915d386ab5719a7da785839 100644 (file)
@@ -2500,6 +2500,90 @@ static int verb_log_level(int argc, char *argv[], void *userdata) {
         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:");
@@ -2609,6 +2693,7 @@ static int native_help(void) {
                "  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"
@@ -3152,7 +3237,7 @@ static int native_parse_argv(int argc, char *argv[]) {
 }
 
 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           },
@@ -3174,8 +3259,10 @@ static int native_main(int argc, char *argv[], sd_bus *bus) {
                 { "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);
 }
index dd27c50b498289b82c593efcf49c8ecc2cbd21f4..49e23ae4503fb4e00f8b925e65b43399ca0e1156 100644 (file)
@@ -132,15 +132,17 @@ static int reply_query_state(DnsQuery *q) {
         }
 }
 
-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)
@@ -165,9 +167,11 @@ static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifin
         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;
 }
@@ -216,7 +220,7 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) {
                 if (r == 0)
                         continue;
 
-                r = append_address(reply, rr, ifindex);
+                r = append_address(reply, rr, ifindex, true);
                 if (r < 0)
                         goto finish;
 
@@ -851,7 +855,7 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr)
                                 if (r == 0)
                                         continue;
 
-                                r = append_address(reply, zz, ifindex);
+                                r = append_address(reply, zz, ifindex, true);
                                 if (r < 0)
                                         return r;
                         }
@@ -2000,6 +2004,76 @@ static int bus_method_unregister_service(sd_bus_message *message, void *userdata
         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),
@@ -2138,9 +2212,14 @@ static const sd_bus_vtable resolve_vtable[] = {
                                 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",
index 75f1ccb6498ef9987d272aebd46bce1e8473c3d9..e199e8f00ce0f122d261a318681dabe9cd2fc71c 100644 (file)
@@ -1066,7 +1066,55 @@ int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p) {
         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)
index 4ab213dc9cd5317d610f0924f41f187d274de42c..6de44cfd054dd6945adbc283f56ce40721afde68 100644 (file)
@@ -27,7 +27,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, bool clamp_ttl, int *rcod
 
 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);
index d77e81ae3986d8f92adae43cdd8465dfea1c1696..d27a19145fc216ddacc81614ede6b319815f719b 100644 (file)
@@ -1159,7 +1159,7 @@ void dns_scope_dump(DnsScope *s, FILE *f) {
 
         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);
         }
 }
 
similarity index 99%
rename from src/shared/machine-image.c
rename to src/shared/discover-image.c
index d2b726efc4c4a6f45eaa63bc468fa8dc2d93b1a7..1f5e4c6f86b345b211f9bd0600418023a33d48c2 100644 (file)
@@ -16,6 +16,7 @@
 #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"
@@ -27,7 +28,6 @@
 #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"
@@ -1065,7 +1065,6 @@ int image_path_lock(const char *path, int operation, LockFile *global, LockFile
                         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;
         }
@@ -1220,11 +1219,16 @@ int image_read_metadata(Image *i) {
 }
 
 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;
 
@@ -1233,11 +1237,9 @@ int image_name_lock(const char *name, int operation, LockFile *ret) {
                 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);
 }
 
index f301a9f610d107d3be65ed1f1a1ca0c862b5fc5d..b1a8ea9ac64a941447cd0068bd2d03af78e730a0 100644 (file)
@@ -79,6 +79,8 @@ shared_sources = files('''
         dev-setup.c
         dev-setup.h
         devnode-acl.h
+        discover-image.c
+        discover-image.h
         dissect-image.c
         dissect-image.h
         dm-util.c
@@ -172,8 +174,6 @@ shared_sources = files('''
         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
index d1cf41283b1b6768dc1b27b3fffc52bbf9e9d1a5..45c10ca9c5600812b686a5be6a63553d2e1472d7 100644 (file)
@@ -1,12 +1,12 @@
 /* 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"
index 601fd63a1442a573c816ce02e21546eb12f39dc8..ee38e49ec92da73c1c2638531b5f8481088be006 100644 (file)
@@ -6,6 +6,7 @@
 #include <unistd.h>
 
 #include "capability-util.h"
+#include "discover-image.h"
 #include "dissect-image.h"
 #include "escape.h"
 #include "fd-util.h"
@@ -14,7 +15,6 @@
 #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"
index 4070c6425770229ad663b0b11d8974ac8346bed8..103f81647d26e5f5d52bd19d2cbb0a8e7220c276 100644 (file)
@@ -6,6 +6,7 @@
 
 #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"
@@ -57,6 +58,8 @@ int logind_reboot(enum action a) {
         };
 
         _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;
 
@@ -75,6 +78,20 @@ int logind_reboot(enum action a) {
         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));
index b28d5d7c16df97c9cadfd0f134012ab320f91795..13b00d6a5b54f056455193112db219af0c3786bc 100644 (file)
@@ -189,7 +189,7 @@ int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *fam
 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);
 
index fcaffa4539107d4cb623f2735a1d307780c08b8c..58b185494df3f456ef1389f97b93ea38a64e425a 100644 (file)
@@ -578,9 +578,9 @@ static void test_path_extract_filename(void) {
         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);
@@ -604,8 +604,7 @@ static void test_path_extract_filename(void) {
 }
 
 static void test_filename_is_valid(void) {
-        char foo[FILENAME_MAX+2];
-        int i;
+        char foo[NAME_MAX+2];
 
         log_info("/* %s */", __func__);
 
@@ -618,9 +617,8 @@ static void test_filename_is_valid(void) {
         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));
 
@@ -628,6 +626,38 @@ static void test_filename_is_valid(void) {
         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__);
 
@@ -761,6 +791,7 @@ int main(int argc, char **argv) {
         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();
index e25cf9e5d91287727ad6da85d4c76557ca0955ac..641cadec858b20ae54cc9f18980387ff0a7bc30a 100644 (file)
@@ -8,6 +8,7 @@
 #include "condition.h"
 #include "device-private.h"
 #include "device.h"
+#include "discover-image.h"
 #include "execute.h"
 #include "import-util.h"
 #include "install.h"
@@ -18,7 +19,6 @@
 #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"
index 1dff9ac8b38696be2c54e502de8d22bba1e66fa4..70c5525b57724f4bb1a95004d11180847aefa4b2 100644 (file)
@@ -41,7 +41,9 @@ Link.Name,                             config_parse_ifname,                   0,
 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)
index dbd804ce7644bf439e2e93971a669441523442a3..0653ae7a9cd1bfbf46614d1a837b06ba8cb198bc 100644 (file)
@@ -427,11 +427,15 @@ static int link_config_apply_rtnl_settings(sd_netlink **rtnl, const link_config
         } 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;
 }
@@ -704,6 +708,40 @@ int config_parse_ifalias(
         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,
index 059c48c8af4b9b19ea51a27437d511bc189f5e66..721f822f85a87900e71b384661fae99dfeed2006 100644 (file)
@@ -46,6 +46,8 @@ struct link_config {
         char *name;
         char **alternative_names;
         char *alias;
+        uint32_t txqueues;
+        uint32_t rxqueues;
         uint32_t txqueuelen;
         uint32_t mtu;
         uint32_t gso_max_segments;
@@ -91,6 +93,7 @@ MACAddressPolicy mac_address_policy_from_string(const char *p) _pure_;
 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);
index a94573bdd651b534e799be9148343a0f53b287e9..112a81930f7ff434405e28c9409e2c47616bb25e 100644 (file)
@@ -20,7 +20,9 @@ Name=
 AlternativeNamesPolicy=
 AlternativeName=
 Alias=
-TxQueueLength=
+TransmitQueues=
+ReceiveQueues=
+TransmitQueueLength=
 MTUBytes=
 BitsPerSecond=
 Duplex=
index e6fb9f6a80b4cc43424b3630a11772a535187c61..1c4f338ad0954a51a602ef3b3ca8b0391380090a 100644 (file)
@@ -40,8 +40,6 @@ Multicast=
 MACAddress=
 Group=
 Promiscuous=
-TransmitQueues=
-ReceiveQueues=
 [SR-IOV]
 VirtualFunction=
 MACSpoofCheck=
index 7813c2c1ba71056375316a363151248a2caaca94..a06f100c34ee902d4cf684e831e8614b1533b0f2 100644 (file)
@@ -2,6 +2,7 @@
 Name=veth-peer
 
 [Network]
+IPv6AcceptRA=no
 IPv6SendRA=yes
 
 [IPv6SendRA]