units: add initrd-cryptsetup.target

For encrypted block devices that we need to unlock from the initramfs,
we currently rely on dracut shipping `cryptsetup.target`. This works,
but doesn't cover the case where the encrypted block device requires
networking (i.e. the `remote-cryptsetup.target` version). That target
however is traditionally dynamically enabled.

Instead, let's rework things here by adding a `initrd-cryptsetup.target`
specifically for initramfs encrypted block device setup. This plays the
role of both `cryptsetup.target` and `remote-cryptsetup.target` in the
initramfs.

Then, adapt `systemd-cryptsetup-generator` to hook all generated
services to this new unit when running from the initrd. This is
analogous to `systemd-fstab-generator` hooking all mounts to
`initrd-fs.target`, regardless of whether they're network-backed or not.
This commit is contained in:
Jonathan Lebon 2020-10-20 16:30:20 -04:00 committed by Lennart Poettering
parent 69f30d4321
commit 6c5496c492
4 changed files with 46 additions and 9 deletions

View File

@ -41,6 +41,7 @@
<filename>hybrid-sleep.target</filename>, <filename>hybrid-sleep.target</filename>,
<filename>suspend-then-hibernate.target</filename>, <filename>suspend-then-hibernate.target</filename>,
<filename>initrd.target</filename>, <filename>initrd.target</filename>,
<filename>initrd-cryptsetup.target</filename>,
<filename>initrd-fs.target</filename>, <filename>initrd-fs.target</filename>,
<filename>initrd-root-device.target</filename>, <filename>initrd-root-device.target</filename>,
<filename>initrd-root-fs.target</filename>, <filename>initrd-root-fs.target</filename>,
@ -182,8 +183,10 @@
<varlistentry> <varlistentry>
<term><filename>cryptsetup.target</filename></term> <term><filename>cryptsetup.target</filename></term>
<listitem> <listitem>
<para>A target that pulls in setup services for all <para>A target that pulls in setup services for local encrypted block devices.
encrypted block devices.</para> See <filename>remote-cryptsetup.target</filename> below for the equivalent target for remote
volumes, and <filename>initrd-cryptsetup.target</filename> below for the equivalent target in the
initrd.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -352,12 +355,20 @@
<varlistentry> <varlistentry>
<term><filename>initrd.target</filename></term> <term><filename>initrd.target</filename></term>
<listitem> <listitem>
<para>This is the default target in the initramfs, similar to <filename>default.target</filename> <para>This is the default target in the initrd, similar to <filename>default.target</filename>
in the main system. It is used to mount the real root and transition to it. See in the main system. It is used to mount the real root and transition to it. See
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
more discussion.</para> more discussion.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><filename>initrd-cryptsetup.target</filename></term>
<listitem>
<para>A target that pulls in setup services for all encrypted block devices. See
<filename>cryptsetup.target</filename> and <filename>remote-cryptsetup.target</filename> for the
equivalent targets in the real root.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><filename>initrd-fs.target</filename></term> <term><filename>initrd-fs.target</filename></term>
<listitem> <listitem>
@ -549,7 +560,9 @@
<para>Similar to <filename>cryptsetup.target</filename>, but for encrypted <para>Similar to <filename>cryptsetup.target</filename>, but for encrypted
devices which are accessed over the network. It is used for devices which are accessed over the network. It is used for
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry> <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
entries marked with <option>_netdev</option>.</para> entries marked with <option>_netdev</option>.
See <filename>cryptsetup.target</filename> for the equivalent target for local volumes, and
<filename>initrd-cryptsetup.target</filename> for the equivalent target in the initrd.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -455,10 +455,16 @@ static int create_disk(
} }
} }
const char *target;
if (in_initrd())
target = "initrd-cryptsetup.target";
else if (netdev)
target = "remote-cryptsetup.target";
else
target = "cryptsetup.target";
if (!nofail) if (!nofail)
fprintf(f, fprintf(f, "Before=%s\n", target);
"Before=%s\n",
netdev ? "remote-cryptsetup.target" : "cryptsetup.target");
if (password && !keydev) { if (password && !keydev) {
r = print_dependencies(f, password); r = print_dependencies(f, password);
@ -521,8 +527,7 @@ static int create_disk(
return log_error_errno(r, "Failed to write unit file %s: %m", n); return log_error_errno(r, "Failed to write unit file %s: %m", n);
if (!noauto) { if (!noauto) {
r = generator_add_symlink(arg_dest, r = generator_add_symlink(arg_dest, target,
netdev ? "remote-cryptsetup.target" : "cryptsetup.target",
nofail ? "wants" : "requires", n); nofail ? "wants" : "requires", n);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -0,0 +1,17 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# 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=Initrd Encrypted Volumes
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
AssertPathExists=/etc/initrd-release
DefaultDependencies=no
Conflicts=shutdown.target

View File

@ -28,6 +28,8 @@ units = [
['hybrid-sleep.target', 'ENABLE_HIBERNATE'], ['hybrid-sleep.target', 'ENABLE_HIBERNATE'],
['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'], ['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'],
['initrd-cleanup.service', 'ENABLE_INITRD'], ['initrd-cleanup.service', 'ENABLE_INITRD'],
['initrd-cryptsetup.target', 'HAVE_LIBCRYPTSETUP ENABLE_INITRD',
'sysinit.target.wants/'],
['initrd-fs.target', 'ENABLE_INITRD'], ['initrd-fs.target', 'ENABLE_INITRD'],
['initrd-parse-etc.service', 'ENABLE_INITRD'], ['initrd-parse-etc.service', 'ENABLE_INITRD'],
['initrd-root-device.target', 'ENABLE_INITRD'], ['initrd-root-device.target', 'ENABLE_INITRD'],