mirror of
https://github.com/systemd/systemd
synced 2025-12-28 11:54:45 +01:00
Compare commits
32 Commits
0132453c40
...
3dc536e0c5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3dc536e0c5 | ||
|
|
38f3e0a58d | ||
|
|
16ed53658a | ||
|
|
95dd454edc | ||
|
|
cda7fc8db3 | ||
|
|
e64652f70c | ||
|
|
a307a7dd38 | ||
|
|
dcd46cc42d | ||
|
|
8eeffefbf0 | ||
|
|
fd9d7de176 | ||
|
|
3ceb6913c7 | ||
|
|
371c8b5d05 | ||
|
|
08b04ec7e7 | ||
|
|
92a74c4744 | ||
|
|
4f38ba3889 | ||
|
|
7a0c0e0e41 | ||
|
|
ecd80ce26c | ||
|
|
b9eea0a753 | ||
|
|
700661ed75 | ||
|
|
f222165e3d | ||
|
|
190b3b5c30 | ||
|
|
967d72ed93 | ||
|
|
03d2d9e18f | ||
|
|
c75165cade | ||
|
|
fb8ac4cf3e | ||
|
|
b77071b898 | ||
|
|
c26f9a9d8c | ||
|
|
c6194e8825 | ||
|
|
1346c36d5a | ||
|
|
65ca9b5343 | ||
|
|
0141102f10 | ||
|
|
cb0198a13c |
@ -49,6 +49,9 @@ All tools:
|
||||
* `$SYSTEMD_CRYPTTAB` — if set, use this path instead of /etc/crypttab. Only
|
||||
useful for debugging. Currently only supported by systemd-cryptsetup-generator.
|
||||
|
||||
* `$SYSTEMD_VERITYTAB` — if set, use this path instead of /etc/veritytab. Only
|
||||
useful for debugging. Currently only supported by systemd-veritysetup-generator.
|
||||
|
||||
* `$SYSTEMD_EFI_OPTIONS` — if set, used instead of the string in the
|
||||
SystemdOptions EFI variable. Analogous to `$SYSTEMD_PROC_CMDLINE`.
|
||||
|
||||
@ -56,7 +59,7 @@ All tools:
|
||||
method. Defaults to `auto`. Behavior is defined as follows:
|
||||
`auto`: Checks if `/etc/initrd-release` exists, and a temporary fs is mounted
|
||||
on `/`. If both conditions meet, then it's in initrd.
|
||||
`lenient`: Similiar to `auto`, but the rootfs check is skipped.
|
||||
`lenient`: Similar to `auto`, but the rootfs check is skipped.
|
||||
`0|1`: Simply overrides initrd detection. This is useful for debugging and
|
||||
testing initrd-only programs in the main system.
|
||||
|
||||
|
||||
@ -92,10 +92,10 @@
|
||||
|
||||
<!-- note: do not use unicode ellipsis here, because docbook will replace that
|
||||
with three dots anyway, messing up alignment -->
|
||||
<programlisting> cryptsetup-pre.target
|
||||
<programlisting> cryptsetup-pre.target veritysetup-pre.target
|
||||
|
|
||||
(various low-level v
|
||||
API VFS mounts: (various cryptsetup devices...)
|
||||
API VFS mounts: (various cryptsetup/veritysetup devices...)
|
||||
mqueue, configfs, | |
|
||||
debugfs, ...) v |
|
||||
| cryptsetup.target |
|
||||
@ -105,7 +105,7 @@
|
||||
| v local-fs-pre.target | | | (network file systems)
|
||||
| swap.target | | v v |
|
||||
| | v | remote-cryptsetup.target |
|
||||
| | (various low-level (various mounts and | | |
|
||||
| | (various low-level (various mounts and | remote-veritysetup.target |
|
||||
| | services: udevd, fsck services...) | | remote-fs.target
|
||||
| | tmpfiles, random | | | /
|
||||
| | seed, sysctl, ...) v | | /
|
||||
@ -303,7 +303,8 @@ emergency.service | | |
|
||||
<programlisting> (conflicts with (conflicts with
|
||||
all system all file system
|
||||
services) mounts, swaps,
|
||||
| cryptsetup
|
||||
| cryptsetup/
|
||||
| veritysetup
|
||||
| devices, ...)
|
||||
| |
|
||||
v v
|
||||
|
||||
@ -94,7 +94,8 @@
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title><filename>/etc/crypttab</filename> and
|
||||
<title><filename>/etc/crypttab</filename>,
|
||||
<filename>/etc/veritytab</filename> and
|
||||
<filename>/etc/fstab</filename> options</title>
|
||||
|
||||
<para>Options which influence mounted filesystems and encrypted volumes.</para>
|
||||
|
||||
@ -356,11 +356,14 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>veritytab=</varname></term>
|
||||
<term><varname>rd.veritytab=</varname></term>
|
||||
<term><varname>roothash=</varname></term>
|
||||
<term><varname>systemd.verity=</varname></term>
|
||||
<term><varname>rd.systemd.verity=</varname></term>
|
||||
<term><varname>systemd.verity_root_data=</varname></term>
|
||||
<term><varname>systemd.verity_root_hash=</varname></term>
|
||||
<term><varname>systemd.verity.root_options=</varname></term>
|
||||
<listitem>
|
||||
<para>Configures the integrity protection root hash for the root file system, and other related
|
||||
parameters. For details, see
|
||||
|
||||
@ -9,6 +9,7 @@ manpages = [
|
||||
['coredump.conf', '5', ['coredump.conf.d'], 'ENABLE_COREDUMP'],
|
||||
['coredumpctl', '1', [], 'ENABLE_COREDUMP'],
|
||||
['crypttab', '5', [], 'HAVE_LIBCRYPTSETUP'],
|
||||
['veritytab', '5', [], 'HAVE_LIBCRYPTSETUP'],
|
||||
['daemon', '7', [], ''],
|
||||
['dnssec-trust-anchors.d',
|
||||
'5',
|
||||
|
||||
@ -1868,7 +1868,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
||||
However, if <literal>no</literal> is specified or <literal>auto</literal> is specified on a
|
||||
non-interactive requests, the established locks are ignored and not shown, and the operation
|
||||
attempted anyway, possibly requiring additional privileges.
|
||||
May be overriden by <option>--force</option>.</para>
|
||||
May be overridden by <option>--force</option>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
<listitem><para>Takes a boolean argument. Defaults to <literal>yes</literal>. If <literal>no</literal>,
|
||||
disables the generator entirely. <varname>rd.systemd.verity=</varname> is honored only by the initial RAM disk
|
||||
(initrd) while <varname>systemd.verity=</varname> is honored by both the host system and the
|
||||
initrd. </para></listitem>
|
||||
initrd.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -81,6 +81,17 @@
|
||||
(see above).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>systemd.verity_root_options=</varname></term>
|
||||
|
||||
<listitem><para>Takes a comma-separated list of dm-verity options. Expects the following options
|
||||
<option>ignore-corruption</option>, <option>restart-on-corruption</option>, <option>ignore-zero-blocks</option>,
|
||||
<option>check-at-most-once</option>, <option>panic-on-corruption</option> and
|
||||
<option>root-hash-signature</option>. See
|
||||
<citerefentry><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more
|
||||
details.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@ -1051,8 +1051,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Scope=</varname></term>
|
||||
<listitem>
|
||||
<para>The scope of the address, which can be <literal>global</literal>,
|
||||
<literal>link</literal> or <literal>host</literal> or an unsigned integer in the range 0—255.
|
||||
<para>The scope of the address, which can be
|
||||
<literal>global</literal> (valid everywhere on the network, even through a gateway),
|
||||
<literal>link</literal> (only valid on this device, will not traverse a gateway) or
|
||||
<literal>host</literal> (only valid within the device itself, e.g. 127.0.0.1)
|
||||
or an unsigned integer in the range 0—255.
|
||||
Defaults to <literal>global</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -1367,12 +1370,32 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Scope=</varname></term>
|
||||
<listitem>
|
||||
<para>The scope of the route, which can be <literal>global</literal>, <literal>site</literal>,
|
||||
<literal>link</literal>, <literal>host</literal>, or <literal>nowhere</literal>. For IPv4 route,
|
||||
defaults to <literal>host</literal> if <varname>Type=</varname> is <literal>local</literal>
|
||||
or <literal>nat</literal>, and <literal>link</literal> if <varname>Type=</varname> is
|
||||
<para>The scope of the IPv4 route, which can be <literal>global</literal>, <literal>site</literal>,
|
||||
<literal>link</literal>, <literal>host</literal>, or
|
||||
<literal>nowhere</literal>:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>global</literal> means the route can reach
|
||||
hosts more than one hop away.</para></listitem>
|
||||
|
||||
<listitem><para><literal>site</literal> means an interior route in
|
||||
the local autonomous system.</para></listitem>
|
||||
|
||||
<listitem><para><literal>link</literal> means the route can only
|
||||
reach hosts on the local network (one hop away).</para></listitem>
|
||||
|
||||
<listitem><para><literal>host</literal> means the route will not
|
||||
leave the local machine (used for internal addresses like
|
||||
127.0.0.1).</para></listitem>
|
||||
|
||||
<listitem><para><literal>nowhere</literal> means the destination
|
||||
doesn't exist.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For IPv4 route, defaults to <literal>host</literal> if <varname>Type=</varname> is
|
||||
<literal>local</literal> or <literal>nat</literal>,
|
||||
and <literal>link</literal> if <varname>Type=</varname> is
|
||||
<literal>broadcast</literal>, <literal>multicast</literal>, or <literal>anycast</literal>.
|
||||
In other cases, defaults to <literal>global</literal>.</para>
|
||||
In other cases, defaults to <literal>global</literal>. The value is
|
||||
not used for IPv6.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
<filename>bluetooth.target</filename>,
|
||||
<filename>cryptsetup-pre.target</filename>,
|
||||
<filename>cryptsetup.target</filename>,
|
||||
<filename>veritysetup-pre.target</filename>,
|
||||
<filename>veritysetup.target</filename>,
|
||||
<filename>ctrl-alt-del.target</filename>,
|
||||
<filename>blockdev@.target</filename>,
|
||||
<filename>boot-complete.target</filename>,
|
||||
@ -60,6 +62,7 @@
|
||||
<filename>printer.target</filename>,
|
||||
<filename>reboot.target</filename>,
|
||||
<filename>remote-cryptsetup.target</filename>,
|
||||
<filename>remote-veritysetup.target</filename>,
|
||||
<filename>remote-fs-pre.target</filename>,
|
||||
<filename>remote-fs.target</filename>,
|
||||
<filename>rescue.target</filename>,
|
||||
@ -186,6 +189,13 @@
|
||||
encrypted block devices.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>veritysetup.target</filename></term>
|
||||
<listitem>
|
||||
<para>A target that pulls in setup services for all
|
||||
verity integrity protected block devices.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>dbus.service</filename></term>
|
||||
<listitem>
|
||||
@ -552,6 +562,15 @@
|
||||
entries marked with <option>_netdev</option>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>remote-veritysetup.target</filename></term>
|
||||
<listitem>
|
||||
<para>Similar to <filename>veritysetup.target</filename>, but for verity
|
||||
integrity protected devices which are accessed over the network. It is used for
|
||||
<citerefentry><refentrytitle>veritytab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
entries marked with <option>_netdev</option>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>remote-fs.target</filename></term>
|
||||
<listitem>
|
||||
@ -855,7 +874,8 @@
|
||||
<listitem><para>This template unit is used to order mount units and other consumers of block
|
||||
devices after services that synthesize these block devices. In particular, this is intended to be
|
||||
used with storage services (such as
|
||||
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
|
||||
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>/
|
||||
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
|
||||
that allocate and manage a virtual block device. Storage services are ordered before an instance of
|
||||
<filename>blockdev@.target</filename>, and the consumer units after it. The ordering is
|
||||
particularly relevant during shutdown, as it ensures that the mount is deactivated first and the
|
||||
@ -879,6 +899,19 @@
|
||||
stopped.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>veritysetup-pre.target</filename></term>
|
||||
<listitem>
|
||||
<para>This passive target unit may be pulled in by services
|
||||
that want to run before any verity integrity protected block
|
||||
device is set up. All verity integrity protected block
|
||||
devices are set up after this target has been reached. Since
|
||||
the shutdown order is implicitly the reverse start-up order
|
||||
between units, this target is particularly useful to ensure
|
||||
that a service is shut down only after all verity integrity
|
||||
protected block devices are fully stopped.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>first-boot-complete.target</filename></term>
|
||||
<listitem>
|
||||
@ -972,7 +1005,7 @@
|
||||
<term><filename>remote-fs-pre.target</filename></term>
|
||||
<listitem>
|
||||
<para>This target unit is automatically ordered before all
|
||||
mount point units (see above) and cryptsetup devices
|
||||
mount point units (see above) and cryptsetup/veritysetup devices
|
||||
marked with the <option>_netdev</option>. It can be used to run
|
||||
certain units before remote encrypted devices and mounts are established.
|
||||
Note that this unit is generally not part of the initial
|
||||
|
||||
198
man/veritytab.xml
Normal file
198
man/veritytab.xml
Normal file
@ -0,0 +1,198 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--*-nxml-*-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
<!--
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
This is based on crypttab(5).
|
||||
|
||||
-->
|
||||
<refentry id="veritytab" conditional='HAVE_LIBCRYPTSETUP' xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>veritytab</title>
|
||||
<productname>systemd</productname>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>veritytab</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>veritytab</refname>
|
||||
<refpurpose>Configuration for verity block devices</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<para><filename>/etc/veritytab</filename></para>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>The <filename>/etc/veritytab</filename> file describes
|
||||
verity integrity protected block devices that are set up during
|
||||
system boot.</para>
|
||||
|
||||
<para>Empty lines and lines starting with the <literal>#</literal>
|
||||
character are ignored. Each of the remaining lines describes one
|
||||
verity integrity protected block device. Fields are delimited by
|
||||
white space.</para>
|
||||
|
||||
<para>Each line is in the form<programlisting><replaceable>volume-name</replaceable> <replaceable>data-device</replaceable> <replaceable>hash-device</replaceable> <replaceable>roothash</replaceable> <replaceable>options</replaceable></programlisting>
|
||||
The first four fields are mandatory, the remaining one is optional.</para>
|
||||
|
||||
<para>The first field contains the name of the resulting verity volume; its block device is set up
|
||||
below <filename>/dev/mapper/</filename>.</para>
|
||||
|
||||
<para>The second field contains a path to the underlying block data device, or a specification of a block device via
|
||||
<literal>UUID=</literal> followed by the UUID.</para>
|
||||
|
||||
<para>The third field contains a path to the underlying block hash device, or a specification of a block device via
|
||||
<literal>UUID=</literal> followed by the UUID.</para>
|
||||
|
||||
<para>The fourth field is the <literal>roothash</literal> in hexadecimal.</para>
|
||||
|
||||
<para>The fifth field, if present, is a comma-delimited list of options. The following options are
|
||||
recognized:</para>
|
||||
|
||||
<variablelist class='fstab-options'>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>ignore-corruption</option></term>
|
||||
<term><option>restart-on-corruption</option></term>
|
||||
<term><option>panic-on-corruption</option></term>
|
||||
|
||||
<listitem><para>Defines what to do if data integrity problem is detected (data corruption). Without these
|
||||
options kernel fails the IO operation with I/O error. With <literal>--ignore-corruption</literal> option the
|
||||
corruption is only logged. With <literal>--restart-on-corruption</literal> or
|
||||
<literal>--panic-on-corruption</literal> the kernel is restarted (panicked) immediately.
|
||||
|
||||
(You have to provide way how to avoid restart loops.)</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>ignore-zero-blocks</option></term>
|
||||
|
||||
<listitem><para>Instruct kernel to not verify blocks that are expected to contain zeroes and always directly
|
||||
return zeroes instead.
|
||||
|
||||
WARNING: Use this option only in very specific cases. This option is available since Linux kernel version 4.5.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>check-at-most-once</option></term>
|
||||
|
||||
<listitem><para>Instruct kernel to verify blocks only the first time they are read from the data device, rather
|
||||
than every time.
|
||||
|
||||
WARNING: It provides a reduced level of security because only offline tampering of the data device's content
|
||||
will be detected, not online tampering. This option is available since Linux kernel version 4.17.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>root-hash-signature=</option></term>
|
||||
|
||||
<listitem><para>A base64 string encoding the root hash signature prefixed by <literal>base64:</literal> or a
|
||||
path to roothash signature file used to verify the root hash (in kernel). This feature requires Linux kernel
|
||||
version 5.4 or more recent.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>_netdev</option></term>
|
||||
|
||||
<listitem><para>Marks this veritysetup device as requiring network. It will be
|
||||
started after the network is available, similarly to
|
||||
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
units marked with <option>_netdev</option>. The service unit to set up this device
|
||||
will be ordered between <filename>remote-fs-pre.target</filename> and
|
||||
<filename>remote-veritysetup.target</filename>, instead of
|
||||
<filename>veritysetup-pre.target</filename> and
|
||||
<filename>veritysetup.target</filename>.</para>
|
||||
|
||||
<para>Hint: if this device is used for a mount point that is specified in
|
||||
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
the <option>_netdev</option> option should also be used for the mount
|
||||
point. Otherwise, a dependency loop might be created where the mount point
|
||||
will be pulled in by <filename>local-fs.target</filename>, while the
|
||||
service to configure the network is usually only started <emphasis>after</emphasis>
|
||||
the local file system has been mounted.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>noauto</option></term>
|
||||
|
||||
<listitem><para>This device will not be added to <filename>veritysetup.target</filename>.
|
||||
This means that it will not be automatically enabled on boot, unless something else pulls
|
||||
it in. In particular, if the device is used for a mount point, it'll be enabled
|
||||
automatically during boot, unless the mount point itself is also disabled with
|
||||
<option>noauto</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>nofail</option></term>
|
||||
|
||||
<listitem><para>This device will not be a hard dependency of
|
||||
<filename>veritysetup.target</filename>. It'll still be pulled in and started, but the system
|
||||
will not wait for the device to show up and be enabled, and boot will not fail if this is
|
||||
unsuccessful. Note that other units that depend on the enabled device may still fail. In
|
||||
particular, if the device is used for a mount point, the mount point itself also needs to
|
||||
have the <option>nofail</option> option, or the boot will fail if the device is not enabled
|
||||
successfully.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>x-initrd.attach</option></term>
|
||||
|
||||
<listitem><para>Setup this verity integrity protected block device in the initramfs, similarly to
|
||||
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
units marked with <option>x-initrd.mount</option>.</para>
|
||||
|
||||
<para>Although it's not necessary to mark the mount entry for the root file system with
|
||||
<option>x-initrd.mount</option>, <option>x-initrd.attach</option> is still recommended with
|
||||
the verity integrity protected block device containing the root file system as otherwise systemd
|
||||
will attempt to detach the device during the regular system shutdown while it's still in
|
||||
use. With this option the device will still be detached but later after the root file
|
||||
system is unmounted.</para>
|
||||
|
||||
<para>All other verity integrity protected block devices that contain file systems mounted in the
|
||||
initramfs should use this option.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>At early boot and when the system manager configuration is
|
||||
reloaded, this file is translated into native systemd units by
|
||||
<citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Examples</title>
|
||||
<example>
|
||||
<title>/etc/veritytab example</title>
|
||||
<para>Set up two verity integrity protected block devices. One using device blocks, another using files.</para>
|
||||
|
||||
<programlisting>usr PARTUUID=783e45ae-7aa3-484a-beef-a80ff9c19cbb PARTUUID=21dc1dfe-4c33-8b48-98a9-918a22eb3e37 36e3f740ad502e2c25e2a23d9c7c17bf0fdad2300b7580842d4b7ec1fb0fa263 auto
|
||||
data /etc/data /etc/hash a5ee4b42f70ae1f46a08a7c92c2e0a20672ad2f514792730f5d49d7606ab8fdf auto
|
||||
</programlisting>
|
||||
</example>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-veritysetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd-veritysetup-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
<citerefentry project='die-net'><refentrytitle>veritysetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
@ -237,6 +237,7 @@ conf.set_quoted('ROOTPREFIX_NOSLASH', rootprefixdir_nosl
|
||||
conf.set_quoted('RANDOM_SEED_DIR', randomseeddir)
|
||||
conf.set_quoted('RANDOM_SEED', join_paths(randomseeddir, 'random-seed'))
|
||||
conf.set_quoted('SYSTEMD_CRYPTSETUP_PATH', join_paths(rootlibexecdir, 'systemd-cryptsetup'))
|
||||
conf.set_quoted('SYSTEMD_VERITYSETUP_PATH', join_paths(rootlibexecdir, 'systemd-veritysetup'))
|
||||
conf.set_quoted('SYSTEM_GENERATOR_DIR', systemgeneratordir)
|
||||
conf.set_quoted('USER_GENERATOR_DIR', usergeneratordir)
|
||||
conf.set_quoted('SYSTEM_ENV_GENERATOR_DIR', systemenvgeneratordir)
|
||||
|
||||
@ -845,6 +845,16 @@ int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBU
|
||||
return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
|
||||
}
|
||||
|
||||
int _hashmap_ensure_put(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) {
|
||||
int r;
|
||||
|
||||
r = _hashmap_ensure_allocated(h, hash_ops HASHMAP_DEBUG_PASS_ARGS);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return hashmap_put(*h, key, value);
|
||||
}
|
||||
|
||||
int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS) {
|
||||
int r;
|
||||
|
||||
|
||||
@ -133,8 +133,11 @@ HashmapBase* _hashmap_copy(HashmapBase *h HASHMAP_DEBUG_PARAMS);
|
||||
#define ordered_hashmap_copy(h) ((OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h) HASHMAP_DEBUG_SRC_ARGS))
|
||||
|
||||
int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
int _hashmap_ensure_put(Hashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS);
|
||||
int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
|
||||
|
||||
#define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
#define hashmap_ensure_put(s, ops, key, value) _hashmap_ensure_put(s, ops, key, value HASHMAP_DEBUG_SRC_ARGS)
|
||||
#define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
int _ordered_hashmap_ensure_put(OrderedHashmap **h, const struct hash_ops *hash_ops, const void *key, void *value HASHMAP_DEBUG_PARAMS);
|
||||
|
||||
@ -70,7 +70,7 @@ bool in_initrd(void) {
|
||||
*
|
||||
* If env var $SYSTEMD_IN_INITRD is not set or set to "auto",
|
||||
* both checks are used. If it's set to "lenient", only check
|
||||
* 1 is used. If set to a booleen value, then the boolean
|
||||
* 1 is used. If set to a boolean value, then the boolean
|
||||
* value is returned.
|
||||
*/
|
||||
|
||||
|
||||
@ -2656,11 +2656,7 @@ int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error) {
|
||||
if (ordered_set_size(h->pending_operations) >= PENDING_OPERATIONS_MAX)
|
||||
return sd_bus_error_setf(error, BUS_ERROR_TOO_MANY_OPERATIONS, "Too many client operations requested");
|
||||
|
||||
r = ordered_set_ensure_allocated(&h->pending_operations, &operation_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_put(h->pending_operations, o);
|
||||
r = ordered_set_ensure_put(&h->pending_operations, &operation_hash_ops, o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -190,11 +190,7 @@ static int network_new(Context *context, const char *name, Network **ret) {
|
||||
.dhcp_use_dns = -1,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&context->networks_by_name, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(context->networks_by_name, network->ifname, network);
|
||||
r = hashmap_ensure_put(&context->networks_by_name, &string_hash_ops, network->ifname, network);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -247,11 +243,7 @@ static int netdev_new(Context *context, const char *_kind, const char *_ifname,
|
||||
.ifname = TAKE_PTR(ifname),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&context->netdevs_by_name, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(context->netdevs_by_name, netdev->ifname, netdev);
|
||||
r = hashmap_ensure_put(&context->netdevs_by_name, &string_hash_ops, netdev->ifname, netdev);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -299,11 +291,7 @@ static int link_new(Context *context, const char *name, struct ether_addr *mac,
|
||||
.mac = *mac,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&context->links_by_name, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(context->links_by_name, link->ifname, link);
|
||||
r = hashmap_ensure_put(&context->links_by_name, &string_hash_ops, link->ifname, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -756,11 +756,9 @@ int netdev_load_one(Manager *manager, const char *filename) {
|
||||
netdev->ifname);
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev);
|
||||
r = hashmap_ensure_put(&netdev->manager->netdevs, &string_hash_ops, netdev->ifname, netdev);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r == -EEXIST) {
|
||||
NetDev *n = hashmap_get(netdev->manager->netdevs, netdev->ifname);
|
||||
|
||||
|
||||
@ -91,11 +91,7 @@ static int wireguard_peer_new_static(Wireguard *w, const char *filename, unsigne
|
||||
|
||||
LIST_PREPEND(peers, w->peers, peer);
|
||||
|
||||
r = hashmap_ensure_allocated(&w->peers_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(w->peers_by_section, peer->section, peer);
|
||||
r = hashmap_ensure_put(&w->peers_by_section, &network_config_hash_ops, peer->section, peer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -580,8 +580,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
size_t allocated = 0, c = 0, j;
|
||||
sd_netlink_message *i;
|
||||
size_t allocated = 0, c = 0;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
@ -606,7 +605,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
for (i = reply; i; i = sd_netlink_message_next(i)) {
|
||||
for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i)) {
|
||||
if (!GREEDY_REALLOC0(links, allocated, c + 2)) /* We keep one trailing one as marker */
|
||||
return -ENOMEM;
|
||||
|
||||
@ -645,7 +644,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
|
||||
typesafe_qsort(links, c, link_info_compare);
|
||||
|
||||
if (bus)
|
||||
for (j = 0; j < c; j++)
|
||||
for (size_t j = 0; j < c; j++)
|
||||
(void) acquire_link_bitrates(bus, links + j);
|
||||
|
||||
*ret = TAKE_PTR(links);
|
||||
@ -891,7 +890,7 @@ static int dump_gateways(
|
||||
int ifindex) {
|
||||
_cleanup_free_ struct local_address *local = NULL;
|
||||
_cleanup_strv_free_ char **buf = NULL;
|
||||
int r, n, i;
|
||||
int r, n;
|
||||
|
||||
assert(rtnl);
|
||||
assert(table);
|
||||
@ -900,7 +899,7 @@ static int dump_gateways(
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
_cleanup_free_ char *gateway = NULL, *description = NULL, *with_description = NULL;
|
||||
char name[IF_NAMESIZE+1];
|
||||
|
||||
|
||||
@ -55,11 +55,7 @@ static int address_label_new_static(Network *network, const char *filename, unsi
|
||||
.section = TAKE_PTR(n),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->address_labels_by_section, label->section, label);
|
||||
r = hashmap_ensure_put(&network->address_labels_by_section, &network_config_hash_ops, label->section, label);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -135,7 +135,6 @@ static bool address_pool_prefix_is_taken(
|
||||
|
||||
static int address_pool_acquire_one(AddressPool *p, int family, unsigned prefixlen, union in_addr_union *found) {
|
||||
union in_addr_union u;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
@ -150,7 +149,7 @@ static int address_pool_acquire_one(AddressPool *p, int family, unsigned prefixl
|
||||
|
||||
u = p->in_addr;
|
||||
|
||||
for (i = 0; i < RANDOM_PREFIX_TRIAL_MAX; i++) {
|
||||
for (unsigned i = 0; i < RANDOM_PREFIX_TRIAL_MAX; i++) {
|
||||
r = in_addr_random_prefix(p->family, &u, p->prefixlen, prefixlen);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -599,7 +599,6 @@ bool link_address_is_dynamic(const Link *link, const Address *address) {
|
||||
|
||||
static int link_enumerate_ipv6_tentative_addresses(Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
sd_netlink_message *addr;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -614,7 +613,7 @@ static int link_enumerate_ipv6_tentative_addresses(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
|
||||
for (sd_netlink_message *addr = reply; addr; addr = sd_netlink_message_next(addr)) {
|
||||
unsigned char flags;
|
||||
int ifindex;
|
||||
|
||||
|
||||
@ -44,9 +44,9 @@ static int find_next_bit(int i, uint32_t x) {
|
||||
|
||||
static int append_vlan_info_data(Link *const link, sd_netlink_message *req, uint16_t pvid, const uint32_t *br_vid_bitmap, const uint32_t *br_untagged_bitmap) {
|
||||
struct bridge_vlan_info br_vlan;
|
||||
int i, j, k, r, cnt;
|
||||
uint16_t begin, end;
|
||||
bool done, untagged = false;
|
||||
uint16_t begin, end;
|
||||
int r, cnt;
|
||||
|
||||
assert(link);
|
||||
assert(req);
|
||||
@ -56,16 +56,17 @@ static int append_vlan_info_data(Link *const link, sd_netlink_message *req, uint
|
||||
cnt = 0;
|
||||
|
||||
begin = end = UINT16_MAX;
|
||||
for (k = 0; k < BRIDGE_VLAN_BITMAP_LEN; k++) {
|
||||
unsigned base_bit;
|
||||
uint32_t vid_map = br_vid_bitmap[k];
|
||||
for (int k = 0; k < BRIDGE_VLAN_BITMAP_LEN; k++) {
|
||||
uint32_t untagged_map = br_untagged_bitmap[k];
|
||||
uint32_t vid_map = br_vid_bitmap[k];
|
||||
unsigned base_bit;
|
||||
int i;
|
||||
|
||||
base_bit = k * 32;
|
||||
i = -1;
|
||||
done = false;
|
||||
do {
|
||||
j = find_next_bit(i, vid_map);
|
||||
int j = find_next_bit(i, vid_map);
|
||||
if (j > 0) {
|
||||
/* first hit of any bit */
|
||||
if (begin == UINT16_MAX && end == UINT16_MAX) {
|
||||
|
||||
@ -809,7 +809,6 @@ int config_parse_dhcp_request_options(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = data;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -826,7 +825,7 @@ int config_parse_dhcp_request_options(
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = rvalue;;) {
|
||||
for (const char *p = rvalue;;) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
@ -163,7 +163,7 @@ static int dhcp_route_configure(Route *route, Link *link) {
|
||||
static int link_set_dns_routes(Link *link, const struct in_addr *address) {
|
||||
const struct in_addr *dns;
|
||||
uint32_t table;
|
||||
int i, n, r;
|
||||
int n, r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp_lease);
|
||||
@ -181,7 +181,7 @@ static int link_set_dns_routes(Link *link, const struct in_addr *address) {
|
||||
|
||||
table = link_get_dhcp_route_table(link);
|
||||
|
||||
for (i = 0; i < n; i ++) {
|
||||
for (int i = 0; i < n; i ++) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
r = route_new(&route);
|
||||
|
||||
@ -309,11 +309,9 @@ static int dhcp6_set_pd_route(Link *link, const union in_addr_union *prefix, con
|
||||
.link = link_ref(link),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&link->manager->dhcp6_prefixes, &in6_addr_hash_ops);
|
||||
if (r < 0)
|
||||
r = hashmap_ensure_put(&link->manager->dhcp6_prefixes, &in6_addr_hash_ops, &pd->prefix, pd);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(link->manager->dhcp6_prefixes, &pd->prefix, pd);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 prefix route at manager: %m");
|
||||
|
||||
|
||||
@ -79,11 +79,7 @@ static int fdb_entry_new_static(
|
||||
.fdb_ntf_flags = NEIGHBOR_CACHE_ENTRY_FLAGS_SELF,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&network->fdb_entries_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->fdb_entries_by_section, fdb_entry->section, fdb_entry);
|
||||
r = hashmap_ensure_put(&network->fdb_entries_by_section, &network_config_hash_ops, fdb_entry->section, fdb_entry);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -449,11 +449,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
|
||||
if (asprintf(&link->lldp_file, "/run/systemd/netif/lldp/%d", link->ifindex) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = hashmap_ensure_allocated(&manager->links, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(manager->links, INT_TO_PTR(link->ifindex), link);
|
||||
r = hashmap_ensure_put(&manager->links, NULL, INT_TO_PTR(link->ifindex), link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1605,11 +1601,7 @@ static int link_put_carrier(Link *link, Link *carrier, Hashmap **h) {
|
||||
if (hashmap_get(*h, INT_TO_PTR(carrier->ifindex)))
|
||||
return 0;
|
||||
|
||||
r = hashmap_ensure_allocated(h, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(*h, INT_TO_PTR(carrier->ifindex), carrier);
|
||||
r = hashmap_ensure_put(h, NULL, INT_TO_PTR(carrier->ifindex), carrier);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -70,11 +70,7 @@ static int mdb_entry_new_static(
|
||||
.section = TAKE_PTR(n),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&network->mdb_entries_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->mdb_entries_by_section, mdb_entry->section, mdb_entry);
|
||||
r = hashmap_ensure_put(&network->mdb_entries_by_section, &network_config_hash_ops, mdb_entry->section, mdb_entry);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -60,11 +60,7 @@ static int neighbor_new_static(Network *network, const char *filename, unsigned
|
||||
.section = TAKE_PTR(n),
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&network->neighbors_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->neighbors_by_section, neighbor->section, neighbor);
|
||||
r = hashmap_ensure_put(&network->neighbors_by_section, &network_config_hash_ops, neighbor->section, neighbor);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -142,11 +142,9 @@ static int network_resolve_stacked_netdevs(Network *network) {
|
||||
if (r <= 0)
|
||||
continue;
|
||||
|
||||
r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops);
|
||||
if (r < 0)
|
||||
r = hashmap_ensure_put(&network->stacked_netdevs, &string_hash_ops, netdev->ifname, netdev);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "%s: Failed to add NetDev '%s' to network: %m",
|
||||
network->filename, (const char *) name);
|
||||
|
||||
@ -79,11 +79,7 @@ static int nexthop_new_static(Network *network, const char *filename, unsigned s
|
||||
nexthop->network = network;
|
||||
nexthop->section = TAKE_PTR(n);
|
||||
|
||||
r = hashmap_ensure_allocated(&network->nexthops_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->nexthops_by_section, nexthop->section, nexthop);
|
||||
r = hashmap_ensure_put(&network->nexthops_by_section, &network_config_hash_ops, nexthop->section, nexthop);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -75,11 +75,7 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
|
||||
prefix->network = network;
|
||||
prefix->section = TAKE_PTR(n);
|
||||
|
||||
r = hashmap_ensure_allocated(&network->prefixes_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->prefixes_by_section, prefix->section, prefix);
|
||||
r = hashmap_ensure_put(&network->prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -227,11 +227,7 @@ static int route_new_static(Network *network, const char *filename, unsigned sec
|
||||
route->network = network;
|
||||
route->section = TAKE_PTR(n);
|
||||
|
||||
r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->routes_by_section, route->section, route);
|
||||
r = hashmap_ensure_put(&network->routes_by_section, &network_config_hash_ops, route->section, route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2193,6 +2189,11 @@ int config_parse_tcp_window(
|
||||
"Specified TCP %s \"%s\" is too large, ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "InitialCongestionWindow"))
|
||||
n->initcwnd = k;
|
||||
|
||||
@ -100,11 +100,7 @@ static int routing_policy_rule_new_static(Network *network, const char *filename
|
||||
rule->section = TAKE_PTR(n);
|
||||
rule->protocol = RTPROT_STATIC;
|
||||
|
||||
r = hashmap_ensure_allocated(&network->rules_by_section, &network_config_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(network->rules_by_section, rule->section, rule);
|
||||
r = hashmap_ensure_put(&network->rules_by_section, &network_config_hash_ops, rule->section, rule);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1067,8 +1063,7 @@ int config_parse_routing_policy_rule_tos(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1104,8 +1099,7 @@ int config_parse_routing_policy_rule_priority(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1141,8 +1135,7 @@ int config_parse_routing_policy_rule_table(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1178,8 +1171,7 @@ int config_parse_routing_policy_rule_fwmark_mask(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1228,8 +1220,7 @@ int config_parse_routing_policy_rule_prefix(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1274,8 +1265,7 @@ int config_parse_routing_policy_rule_device(
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1319,8 +1309,7 @@ int config_parse_routing_policy_rule_port_range(
|
||||
n->dport.end = high;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1358,8 +1347,7 @@ int config_parse_routing_policy_rule_ip_protocol(
|
||||
|
||||
n->ipproto = r;
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1397,8 +1385,7 @@ int config_parse_routing_policy_rule_invert(
|
||||
|
||||
n->invert_rule = r;
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1437,8 +1424,8 @@ int config_parse_routing_policy_rule_family(
|
||||
}
|
||||
|
||||
n->address_family = a;
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1483,8 +1470,8 @@ int config_parse_routing_policy_rule_uid_range(
|
||||
|
||||
n->uid_range.start = start;
|
||||
n->uid_range.end = end;
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1524,8 +1511,7 @@ int config_parse_routing_policy_rule_suppress_prefixlen(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1563,8 +1549,8 @@ int config_parse_routing_policy_rule_type(
|
||||
}
|
||||
|
||||
n->type = (uint8_t) t;
|
||||
n = NULL;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +44,6 @@ static int process_message(Manager *manager, sd_netlink_message *message) {
|
||||
static int speed_meter_handler(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
Manager *manager = userdata;
|
||||
sd_netlink_message *i;
|
||||
usec_t usec_now;
|
||||
Link *link;
|
||||
int r;
|
||||
@ -84,7 +83,7 @@ static int speed_meter_handler(sd_event_source *s, uint64_t usec, void *userdata
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = reply; i; i = sd_netlink_message_next(i))
|
||||
for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i))
|
||||
(void) process_message(manager, i);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -67,12 +67,11 @@ static void test_config_parse_hwaddr_one(const char *rvalue, int ret, const stru
|
||||
|
||||
static void test_config_parse_hwaddrs_one(const char *rvalue, const struct ether_addr* list, size_t n) {
|
||||
_cleanup_set_free_free_ Set *s = NULL;
|
||||
size_t m;
|
||||
|
||||
assert_se(config_parse_hwaddrs("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &s, NULL) == 0);
|
||||
assert_se(set_size(s) == n);
|
||||
|
||||
for (m = 0; m < n; m++) {
|
||||
for (size_t m = 0; m < n; m++) {
|
||||
_cleanup_free_ struct ether_addr *q = NULL;
|
||||
|
||||
assert_se(q = set_remove(s, &list[m]));
|
||||
|
||||
@ -207,7 +207,6 @@ static int on_rtnl_event(sd_netlink *rtnl, sd_netlink_message *mm, void *userdat
|
||||
|
||||
static int manager_rtnl_listen(Manager *m) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
sd_netlink_message *i;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@ -242,7 +241,7 @@ static int manager_rtnl_listen(Manager *m) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (i = reply; i; i = sd_netlink_message_next(i)) {
|
||||
for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i)) {
|
||||
r = manager_process_link(m->rtnl, i, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -83,11 +83,9 @@ static int parse_interface_with_operstate_range(const char *str) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid interface name '%s'", ifname);
|
||||
|
||||
r = hashmap_ensure_allocated(&arg_interfaces, &string_hash_ops);
|
||||
if (r < 0)
|
||||
r = hashmap_ensure_put(&arg_interfaces, &string_hash_ops, ifname, TAKE_PTR(range));
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(arg_interfaces, ifname, TAKE_PTR(range));
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to store interface name: %m");
|
||||
if (r == 0)
|
||||
|
||||
@ -620,6 +620,81 @@ int generator_write_cryptsetup_service_section(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generator_write_veritysetup_unit_section(
|
||||
FILE *f,
|
||||
const char *source) {
|
||||
|
||||
assert(f);
|
||||
|
||||
fprintf(f,
|
||||
"[Unit]\n"
|
||||
"Description=Integrity Protection Setup for %%I\n"
|
||||
"Documentation=man:veritytab(5) man:systemd-veritysetup-generator(8) man:systemd-veritysetup@.service(8)\n");
|
||||
|
||||
if (source)
|
||||
fprintf(f, "SourcePath=%s\n", source);
|
||||
|
||||
fprintf(f,
|
||||
"DefaultDependencies=no\n"
|
||||
"IgnoreOnIsolate=true\n"
|
||||
"After=cryptsetup-pre.target systemd-udevd-kernel.socket\n"
|
||||
"Before=blockdev@dev-mapper-%%i.target\n"
|
||||
"Wants=blockdev@dev-mapper-%%i.target\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generator_write_veritysetup_service_section(
|
||||
FILE *f,
|
||||
const char *name,
|
||||
const char *data_what,
|
||||
const char *hash_what,
|
||||
const char *roothash,
|
||||
const char *options) {
|
||||
|
||||
_cleanup_free_ char *name_escaped = NULL, *data_what_escaped = NULL, *hash_what_escaped,
|
||||
*roothash_escaped = NULL, *options_escaped = NULL;
|
||||
|
||||
assert(f);
|
||||
assert(name);
|
||||
assert(data_what);
|
||||
assert(hash_what);
|
||||
|
||||
name_escaped = specifier_escape(name);
|
||||
if (!name_escaped)
|
||||
return log_oom();
|
||||
|
||||
data_what_escaped = specifier_escape(data_what);
|
||||
if (!data_what_escaped)
|
||||
return log_oom();
|
||||
|
||||
hash_what_escaped = specifier_escape(hash_what);
|
||||
if (!hash_what_escaped)
|
||||
return log_oom();
|
||||
|
||||
roothash_escaped = specifier_escape(roothash);
|
||||
if (!roothash_escaped)
|
||||
return log_oom();
|
||||
|
||||
if (options) {
|
||||
options_escaped = specifier_escape(options);
|
||||
if (!options_escaped)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"\n"
|
||||
"[Service]\n"
|
||||
"Type=oneshot\n"
|
||||
"RemainAfterExit=yes\n"
|
||||
"ExecStart=" SYSTEMD_VERITYSETUP_PATH " attach '%s' '%s' '%s' '%s' '%s'\n"
|
||||
"ExecStop=" SYSTEMD_VERITYSETUP_PATH " detach '%s'\n",
|
||||
name_escaped, data_what_escaped, hash_what_escaped, roothash_escaped, strempty(options_escaped),
|
||||
name_escaped);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void log_setup_generator(void) {
|
||||
/* Disable talking to syslog/journal (i.e. the two IPC-based loggers) if we run in system context. */
|
||||
if (cg_pid_get_owner_uid(0, NULL) == -ENXIO /* not running in a per-user slice */)
|
||||
|
||||
@ -42,6 +42,18 @@ int generator_write_cryptsetup_service_section(
|
||||
const char *password,
|
||||
const char *options);
|
||||
|
||||
int generator_write_veritysetup_unit_section(
|
||||
FILE *f,
|
||||
const char *source);
|
||||
|
||||
int generator_write_veritysetup_service_section(
|
||||
FILE *f,
|
||||
const char *name,
|
||||
const char *data_what,
|
||||
const char *hash_what,
|
||||
const char *roothash,
|
||||
const char *options);
|
||||
|
||||
int generator_write_device_deps(
|
||||
const char *dir,
|
||||
const char *what,
|
||||
|
||||
@ -211,11 +211,7 @@ static int worker_new(struct worker **ret, Manager *manager, sd_device_monitor *
|
||||
.pid = pid,
|
||||
};
|
||||
|
||||
r = hashmap_ensure_allocated(&manager->workers, &worker_hash_op);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = hashmap_put(manager->workers, PID_TO_PTR(pid), worker);
|
||||
r = hashmap_ensure_put(&manager->workers, &worker_hash_op, PID_TO_PTR(pid), worker);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dropin.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fstab-util.h"
|
||||
@ -24,18 +25,33 @@
|
||||
|
||||
#define SYSTEMD_VERITYSETUP_SERVICE "systemd-veritysetup@root.service"
|
||||
|
||||
typedef struct verity_device {
|
||||
char *uuid;
|
||||
char *datadev;
|
||||
char *hashdev;
|
||||
char *roothash;
|
||||
char *name;
|
||||
char *options;
|
||||
bool create;
|
||||
} verity_device;
|
||||
|
||||
static const char *arg_dest = NULL;
|
||||
static bool arg_enabled = true;
|
||||
static bool arg_read_veritytab = true;
|
||||
static const char *arg_veritytab = NULL;
|
||||
static char *arg_root_hash = NULL;
|
||||
static char *arg_data_what = NULL;
|
||||
static char *arg_hash_what = NULL;
|
||||
static char *arg_options = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root_hash, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_data_what, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_hash_what, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_options, freep);
|
||||
|
||||
static int create_device(void) {
|
||||
_cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL, *root_hash_escaped = NULL;
|
||||
_cleanup_free_ char *u = NULL, *v = NULL, *d = NULL, *e = NULL, *u_escaped = NULL, *v_escaped = NULL,
|
||||
*root_hash_escaped = NULL, *options_escaped = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *to;
|
||||
int r;
|
||||
@ -57,7 +73,8 @@ static int create_device(void) {
|
||||
|
||||
log_debug("Using root verity data device %s,\n"
|
||||
" hash device %s,\n"
|
||||
" and root hash %s.", arg_data_what, arg_hash_what, arg_root_hash);
|
||||
" options %s,\n"
|
||||
" and root hash %s.", arg_data_what, arg_hash_what, arg_options, arg_root_hash);
|
||||
|
||||
u = fstab_node_to_udev_node(arg_data_what);
|
||||
if (!u)
|
||||
@ -80,6 +97,10 @@ static int create_device(void) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
options_escaped = specifier_escape(arg_options ?: "");
|
||||
if (!options_escaped)
|
||||
return log_oom();
|
||||
|
||||
root_hash_escaped = specifier_escape(arg_root_hash);
|
||||
if (!root_hash_escaped)
|
||||
return log_oom();
|
||||
@ -97,22 +118,22 @@ static int create_device(void) {
|
||||
"Conflicts=umount.target\n"
|
||||
"BindsTo=%s %s\n"
|
||||
"IgnoreOnIsolate=true\n"
|
||||
"After=cryptsetup-pre.target systemd-udevd-kernel.socket %s %s\n"
|
||||
"Before=cryptsetup.target umount.target\n"
|
||||
"After=veritysetup-pre.target systemd-udevd-kernel.socket %s %s\n"
|
||||
"Before=veritysetup.target umount.target\n"
|
||||
"\n[Service]\n"
|
||||
"Type=oneshot\n"
|
||||
"RemainAfterExit=yes\n"
|
||||
"ExecStart=" ROOTLIBEXECDIR "/systemd-veritysetup attach root '%s' '%s' '%s'\n"
|
||||
"ExecStart=" ROOTLIBEXECDIR "/systemd-veritysetup attach root '%s' '%s' '%s' '%s'\n"
|
||||
"ExecStop=" ROOTLIBEXECDIR "/systemd-veritysetup detach root\n",
|
||||
d, e,
|
||||
d, e,
|
||||
u_escaped, v_escaped, root_hash_escaped);
|
||||
u_escaped, v_escaped, root_hash_escaped, options_escaped);
|
||||
|
||||
r = fflush_and_check(f);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write file unit "SYSTEMD_VERITYSETUP_SERVICE": %m");
|
||||
|
||||
to = strjoina(arg_dest, "/cryptsetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE);
|
||||
to = strjoina(arg_dest, "/veritysetup.target.requires/" SYSTEMD_VERITYSETUP_SERVICE);
|
||||
|
||||
(void) mkdir_parents(to, 0755);
|
||||
if (symlink("../" SYSTEMD_VERITYSETUP_SERVICE, to) < 0)
|
||||
@ -132,6 +153,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
else
|
||||
arg_enabled = r;
|
||||
|
||||
} else if (streq(key, "veritytab")) {
|
||||
|
||||
r = value ? parse_boolean(value) : 1;
|
||||
if (r < 0)
|
||||
log_warning("Failed to parse veritytab= kernel command line switch %s. Ignoring.", value);
|
||||
else
|
||||
arg_read_veritytab = r;
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "roothash")) {
|
||||
|
||||
if (proc_cmdline_value_missing(key, value))
|
||||
@ -158,6 +187,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||
r = free_and_strdup(&arg_hash_what, value);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "systemd.verity_root_options")) {
|
||||
|
||||
if (proc_cmdline_value_missing(key, value))
|
||||
return 0;
|
||||
|
||||
r = free_and_strdup(&arg_options, value);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -205,21 +244,221 @@ static int determine_devices(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int create_disk(
|
||||
const char *name,
|
||||
const char *data_device,
|
||||
const char *hash_device,
|
||||
const char *roothash,
|
||||
const char *options,
|
||||
const char *source) {
|
||||
|
||||
_cleanup_free_ char *n = NULL, *dd = NULL, *du = NULL, *hd = NULL, *hu = NULL, *e = NULL,
|
||||
*du_escaped = NULL, *hu_escaped = NULL, *name_escaped = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
const char *dmname;
|
||||
bool noauto, nofail, netdev, attach_in_initrd;
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(data_device);
|
||||
assert(hash_device);
|
||||
assert(roothash);
|
||||
|
||||
noauto = fstab_test_yes_no_option(options, "noauto\0" "auto\0");
|
||||
nofail = fstab_test_yes_no_option(options, "nofail\0" "fail\0");
|
||||
netdev = fstab_test_option(options, "_netdev\0");
|
||||
attach_in_initrd = fstab_test_option(options, "x-initrd.attach\0");
|
||||
|
||||
name_escaped = specifier_escape(name);
|
||||
if (!name_escaped)
|
||||
return log_oom();
|
||||
|
||||
e = unit_name_escape(name);
|
||||
if (!e)
|
||||
return log_oom();
|
||||
|
||||
du = fstab_node_to_udev_node(data_device);
|
||||
if (!du)
|
||||
return log_oom();
|
||||
|
||||
hu = fstab_node_to_udev_node(hash_device);
|
||||
if (!hu)
|
||||
return log_oom();
|
||||
|
||||
r = unit_name_build("systemd-veritysetup", e, ".service", &n);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
du_escaped = specifier_escape(du);
|
||||
if (!du_escaped)
|
||||
return log_oom();
|
||||
|
||||
hu_escaped = specifier_escape(hu);
|
||||
if (!hu_escaped)
|
||||
return log_oom();
|
||||
|
||||
r = unit_name_from_path(du, ".device", &dd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
r = unit_name_from_path(hu, ".device", &hd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate unit name: %m");
|
||||
|
||||
r = generator_open_unit_file(arg_dest, NULL, n, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = generator_write_veritysetup_unit_section(f, source);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (netdev)
|
||||
fprintf(f, "After=remote-fs-pre.target\n");
|
||||
|
||||
/* If initrd takes care of attaching the disk then it should also detach it during shutdown. */
|
||||
if (!attach_in_initrd)
|
||||
fprintf(f, "Conflicts=umount.target\n");
|
||||
|
||||
if (!nofail)
|
||||
fprintf(f,
|
||||
"Before=%s\n",
|
||||
netdev ? "remote-veritysetup.target" : "veritysetup.target");
|
||||
|
||||
if (path_startswith(du, "/dev/"))
|
||||
fprintf(f,
|
||||
"BindsTo=%s\n"
|
||||
"After=%s\n"
|
||||
"Before=umount.target\n",
|
||||
dd, dd);
|
||||
else
|
||||
/* For loopback devices, add systemd-tmpfiles-setup-dev.service
|
||||
dependency to ensure that loopback support is available in
|
||||
the kernel (/dev/loop-control needs to exist) */
|
||||
fprintf(f,
|
||||
"RequiresMountsFor=%s\n"
|
||||
"Requires=systemd-tmpfiles-setup-dev.service\n"
|
||||
"After=systemd-tmpfiles-setup-dev.service\n",
|
||||
du_escaped);
|
||||
|
||||
if (path_startswith(hu, "/dev/"))
|
||||
fprintf(f,
|
||||
"BindsTo=%s\n"
|
||||
"After=%s\n"
|
||||
"Before=umount.target\n",
|
||||
hd, hd);
|
||||
else
|
||||
/* For loopback devices, add systemd-tmpfiles-setup-dev.service
|
||||
dependency to ensure that loopback support is available in
|
||||
the kernel (/dev/loop-control needs to exist) */
|
||||
fprintf(f,
|
||||
"RequiresMountsFor=%s\n"
|
||||
"Requires=systemd-tmpfiles-setup-dev.service\n"
|
||||
"After=systemd-tmpfiles-setup-dev.service\n",
|
||||
hu_escaped);
|
||||
|
||||
r = generator_write_veritysetup_service_section(f, name, du_escaped, hu_escaped, roothash, options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = fflush_and_check(f);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write unit file %s: %m", n);
|
||||
|
||||
if (!noauto) {
|
||||
r = generator_add_symlink(arg_dest,
|
||||
netdev ? "remote-veritysetup.target" : "veritysetup.target",
|
||||
nofail ? "wants" : "requires", n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
dmname = strjoina("dev-mapper-", e, ".device");
|
||||
return generator_add_symlink(arg_dest, dmname, "requires", n);
|
||||
}
|
||||
|
||||
static int add_veritytab_devices(void) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
unsigned veritytab_line = 0;
|
||||
int r;
|
||||
|
||||
if (!arg_read_veritytab)
|
||||
return 0;
|
||||
|
||||
r = fopen_unlocked(arg_veritytab, "re", &f);
|
||||
if (r < 0) {
|
||||
if (errno != ENOENT)
|
||||
log_error_errno(errno, "Failed to open %s: %m", arg_veritytab);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *line = NULL, *name = NULL, *data_device = NULL, *hash_device = NULL,
|
||||
*roothash = NULL, *options = NULL;
|
||||
verity_device *d = NULL;
|
||||
char *l, *data_uuid, *hash_uuid;
|
||||
int k;
|
||||
|
||||
r = read_line(f, LONG_LINE_MAX, &line);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read %s: %m", arg_veritytab);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
veritytab_line++;
|
||||
|
||||
l = strstrip(line);
|
||||
if (IN_SET(l[0], 0, '#'))
|
||||
continue;
|
||||
|
||||
k = sscanf(l, "%ms %ms %ms %ms %ms", &name, &data_device, &hash_device, &roothash, &options);
|
||||
if (k < 4 || k > 5) {
|
||||
log_error("Failed to parse %s:%u, ignoring.", arg_veritytab, veritytab_line);
|
||||
continue;
|
||||
}
|
||||
|
||||
data_uuid = startswith(data_device, "UUID=");
|
||||
if (!data_uuid)
|
||||
data_uuid = path_startswith(data_device, "/dev/disk/by-uuid/");
|
||||
|
||||
hash_uuid = startswith(hash_device, "UUID=");
|
||||
if (!hash_uuid)
|
||||
hash_uuid = path_startswith(hash_device, "/dev/disk/by-uuid/");
|
||||
|
||||
r = create_disk(name,
|
||||
data_device,
|
||||
hash_device,
|
||||
roothash,
|
||||
options,
|
||||
arg_veritytab);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (d)
|
||||
d->create = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int run(const char *dest, const char *dest_early, const char *dest_late) {
|
||||
int r;
|
||||
|
||||
assert_se(arg_dest = dest);
|
||||
|
||||
arg_veritytab = getenv("SYSTEMD_VERITYTAB") ?: "/etc/veritytab";
|
||||
|
||||
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to parse kernel command line: %m");
|
||||
|
||||
/* For now we only support the root device on verity. Later on we might want to add support for /etc/veritytab
|
||||
* or similar to define additional mappings */
|
||||
|
||||
if (!arg_enabled)
|
||||
return 0;
|
||||
|
||||
r = add_veritytab_devices();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = determine_devices();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -15,13 +15,10 @@
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
|
||||
static char *arg_root_hash = NULL;
|
||||
static char *arg_data_what = NULL;
|
||||
static char *arg_hash_what = NULL;
|
||||
static uint32_t arg_activate_flags = CRYPT_ACTIVATE_READONLY;
|
||||
static char *arg_root_hash_signature = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root_hash, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_data_what, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_hash_what, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_root_hash_signature, freep);
|
||||
|
||||
static int help(void) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
@ -31,7 +28,7 @@ static int help(void) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [ROOTHASHSIG]\n"
|
||||
printf("%s attach VOLUME DATADEVICE HASHDEVICE ROOTHASH [OPTIONS]\n"
|
||||
"%s detach VOLUME\n\n"
|
||||
"Attaches or detaches an integrity protected block device.\n"
|
||||
"\nSee the %s for details.\n"
|
||||
@ -43,6 +40,93 @@ static int help(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int looks_like_roothashsig(const char *option) {
|
||||
const char *val;
|
||||
int r;
|
||||
|
||||
if (path_is_absolute(option)) {
|
||||
|
||||
r = free_and_strdup(&arg_root_hash_signature, option);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
val = startswith(option, "base64:");
|
||||
if (val) {
|
||||
|
||||
r = free_and_strdup(&arg_root_hash_signature, val);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_options(const char *options) {
|
||||
int r;
|
||||
|
||||
/* backward compatibility with the obsolete ROOTHASHSIG positional argument */
|
||||
r = looks_like_roothashsig(options);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 1) {
|
||||
log_warning("Usage of ROOTHASHSIG positional argument is deprecated. "
|
||||
"Please use the option root-hash-signature=%s instead.", options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
char *val;
|
||||
|
||||
r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse options: %m");
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (STR_IN_SET(word, "noauto", "auto", "nofail", "fail", "_netdev"))
|
||||
continue;
|
||||
|
||||
if (isempty(word))
|
||||
continue;
|
||||
else if (streq(word, "ignore-corruption"))
|
||||
arg_activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
|
||||
else if (streq(word, "restart-on-corruption"))
|
||||
arg_activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
|
||||
else if (streq(word, "ignore-zero-blocks"))
|
||||
arg_activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
|
||||
#ifdef CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE
|
||||
else if (streq(word, "check-at-most-once"))
|
||||
arg_activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
|
||||
#endif
|
||||
#ifdef CRYPT_ACTIVATE_PANIC_ON_CORRUPTION
|
||||
else if (streq(word, "panic-on-corruption"))
|
||||
arg_activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
|
||||
#endif
|
||||
else if ((val = startswith(word, "root-hash-signature="))) {
|
||||
|
||||
r = looks_like_roothashsig(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "root-hash-signature expects either full path to signature file or "
|
||||
"base64 string encoding signature prefixed by base64:.");
|
||||
|
||||
r = free_and_strdup(&arg_root_hash_signature, val);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
} else
|
||||
log_warning("Encountered unknown option '%s', ignoring.", word);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||
int r;
|
||||
@ -81,6 +165,12 @@ static int run(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc > 6) {
|
||||
r = parse_options(argv[6]);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse options: %m");
|
||||
}
|
||||
|
||||
r = crypt_load(cd, CRYPT_VERITY, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load verity superblock: %m");
|
||||
@ -89,19 +179,19 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to configure data device: %m");
|
||||
|
||||
if (argc > 6) {
|
||||
if (arg_root_hash_signature && *arg_root_hash_signature) {
|
||||
#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
|
||||
_cleanup_free_ char *hash_sig = NULL;
|
||||
size_t hash_sig_size;
|
||||
char *value;
|
||||
|
||||
if ((value = startswith(argv[6], "base64:"))) {
|
||||
if ((value = startswith(arg_root_hash_signature, "base64:"))) {
|
||||
r = unbase64mem(value, strlen(value), (void *)&hash_sig, &hash_sig_size);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse root hash signature '%s': %m", argv[6]);
|
||||
return log_error_errno(r, "Failed to parse root hash signature '%s': %m", arg_root_hash_signature);
|
||||
} else {
|
||||
r = read_full_file_full(
|
||||
AT_FDCWD, argv[6], UINT64_MAX, SIZE_MAX,
|
||||
AT_FDCWD, arg_root_hash_signature, UINT64_MAX, SIZE_MAX,
|
||||
READ_FULL_FILE_CONNECT_SOCKET,
|
||||
NULL,
|
||||
&hash_sig, &hash_sig_size);
|
||||
@ -109,12 +199,12 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to read root hash signature: %m");
|
||||
}
|
||||
|
||||
r = crypt_activate_by_signed_key(cd, argv[2], m, l, hash_sig, hash_sig_size, CRYPT_ACTIVATE_READONLY);
|
||||
r = crypt_activate_by_signed_key(cd, argv[2], m, l, hash_sig, hash_sig_size, arg_activate_flags);
|
||||
#else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "activation of verity device with signature %s requested, but not supported by cryptsetup due to missing crypt_activate_by_signed_key()", argv[6]);
|
||||
#endif
|
||||
} else
|
||||
r = crypt_activate_by_volume_key(cd, argv[2], m, l, CRYPT_ACTIVATE_READONLY);
|
||||
r = crypt_activate_by_volume_key(cd, argv[2], m, l, arg_activate_flags);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up verity device: %m");
|
||||
|
||||
|
||||
@ -326,6 +326,7 @@ systemd.unit=
|
||||
systemd.verity=
|
||||
systemd.verity_root_data=
|
||||
systemd.verity_root_hash=
|
||||
systemd.verity_root_options=
|
||||
systemd.volatile=
|
||||
systemd.wants=
|
||||
systemd.watchdog_device=
|
||||
|
||||
@ -10,6 +10,9 @@ units = [
|
||||
['cryptsetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
||||
['cryptsetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||
'sysinit.target.wants/'],
|
||||
['veritysetup-pre.target', 'HAVE_LIBCRYPTSETUP'],
|
||||
['veritysetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||
'sysinit.target.wants/'],
|
||||
['dev-hugepages.mount', '',
|
||||
'sysinit.target.wants/'],
|
||||
['dev-mqueue.mount', '',
|
||||
@ -62,6 +65,8 @@ units = [
|
||||
'ctrl-alt-del.target' + (with_runlevels ? ' runlevel6.target' : '')],
|
||||
['remote-cryptsetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||
'initrd-root-device.target.wants/'],
|
||||
['remote-veritysetup.target', 'HAVE_LIBCRYPTSETUP',
|
||||
'initrd-root-device.target.wants/'],
|
||||
['remote-fs-pre.target', ''],
|
||||
['remote-fs.target', ''],
|
||||
['rescue.target', '',
|
||||
|
||||
18
units/remote-veritysetup.target
Normal file
18
units/remote-veritysetup.target
Normal file
@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Remote Verity Integrity Protected Volumes
|
||||
Documentation=man:systemd.special(7)
|
||||
After=remote-fs-pre.target veritysetup-pre.target
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
14
units/veritysetup-pre.target
Normal file
14
units/veritysetup-pre.target
Normal file
@ -0,0 +1,14 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Local Verity Integrity Protected Volumes (Pre)
|
||||
Documentation=man:systemd.special(7)
|
||||
RefuseManualStart=yes
|
||||
Before=veritysetup.target
|
||||
12
units/veritysetup.target
Normal file
12
units/veritysetup.target
Normal file
@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Local Verity Integrity Protected Volumes
|
||||
Documentation=man:systemd.special(7)
|
||||
Loading…
x
Reference in New Issue
Block a user