#983708 systemd-cryptsetup@.service should ignore targets that are already mapped

Package:
systemd
Source:
systemd
Description:
system and service manager
Submitter:
Date:
2021-03-20 19:33:06 UTC
Severity:
normal
#983708#5
Date:
2021-02-28 18:11:56 UTC
From:
To:
systemd  247.2-5~bpo10+1

I recently switched to buster-backports and noticed an issue that (I think) could potentially break
systems migrating to bullseye.
On a system having encrypted root, keyfile on usb-stick and multiple btrfs subvolumes, the system
fails to mount all subvolumes.

If there is no solution, then maybe a hint in the README could be added.

== Root cause ==

/etc/crypttab is used by passdev and systemd, but using different syntax
passdev expects[1] <device>:<file>
systemd expects[2] <file>:<device>


== Setup ==

/etc/crypttab
(this is in one line, split to avoid random line breaks)
root-luks
/dev/sda2
/dev/disk/by-label/usbkeys:/root.key
luks,keyscript=passdev,initramfs


/etc/fstab
/dev/sda1                /boot       ext2
/dev/mapper/root-luks    /           btrfs subvol=@
/dev/mapper/root-luks    /.snapshots btrfs subvol=@snapshots
/dev/mapper/root-luks    /home       btrfs subvol=@home


== Observed issues ==

1. grub starts initramfs
2. cryptsetup-initramfs opens root-luks
3. systemd-cryptsetup-generator starts
4. Error: failed to mount run-systemd-cryptsetup-keydev\\x2droot\\x2dluks.mount
5. .snapshots and home is not mounted because of missing "dependency" for root-luks


== Workaround ==

create a systemd-mount file for the usb-stick
/etc/systemd/system/run-systemd-cryptsetup-keydev\\x2droot\\x2dluks.mount
What=/dev/disk/by-label/usbkeys
Where=/run/systemd/cryptsetup/keydev-root-luks
Options=ro

== References ==
1. /usr/share/doc/cryptsetup-initramfs/README.initramfs.gz
2. https://www.freedesktop.org/software/systemd/man/crypttab.html

#983708#10
Date:
2021-03-20 19:28:16 UTC
From:
To:
Hi,

We (src:crypttab) have precise semantics crypttab(5)'s 3rd column (after
unescaping octal-sequences):

 - if a key script is used, the value of the 3rd column is used as 1st
   positional argument;
 - if the value is "none", the passphrase is read interactively from the
   console;
 - otherwise the assume is assumed to be an existing file or
   block/character device and the passphrase is read from it.

In particular, one might very well use a key file named ‘/etc/my.key:LABEL=keydev’
in the 3rd column, or use ‘foo:bar:baz’ and have a custom keyscript
split the string and interpret it as 3 arguments.  (Our passkev key
script does that with ‘blockdev:keyfile’ for instance.)

I'm thus reassign this to systemd.  With systemd 241-7~deb10u6
‘/etc/my.key:LABEL=keydev’ is interpreted as the path to a key file,
while after upgrading to Bullseye it ignores that file and waits for a
block device with label ‘keydev’ to show up.  This is arguably not a
severe regression though. :-)

However the device might have been mapped at an earlier stage (for
instance at initramfs stage), and systemd-cryptsetup-generator should
not generate units in that case; unlocking might have been done using a
crypttab(5) entry systemd doesn't understand, cf. for instance -1 or
#618862.  At the very least it shouldn't delay the boot or end up in a
failed state.

AFAICT while systemd delays the boot until the device lookup timeouts
(and ends up in a failed state), if the mapped target contains a file
system with a matching fstab(5) entry then systemd does mount it.  But
unlike the OP I've only tried with ext4 not multi-volume btrfs.

Cheers