unsuccessful. Note that other units that depend on the unlocked 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 unlocked
- successfully.</para>
+ successfully. If a keyfile and/or a <option>header</option> are specified, the dependencies on
+ their respective directories will also not be fatal, so that umounting said directories will
+ not cause the generated cryptset unit to be deactivated.</para>
<xi:include href="version-info.xml" xpointer="v186"/></listitem>
</varlistentry>
static int print_dependencies(FILE *f, const char* device_path, const char* timeout_value, bool canfail) {
int r;
- assert(!canfail || timeout_value);
+ assert(f);
+ assert(device_path);
if (STR_IN_SET(device_path, "-", "none"))
/* None, nothing to do */
fprintf(f, "After=%1$s\n", unit);
if (canfail) {
fprintf(f, "Wants=%1$s\n", unit);
- r = write_drop_in_format(arg_dest, unit, 90, "device-timeout",
- "# Automatically generated by systemd-cryptsetup-generator \n\n"
- "[Unit]\nJobRunningTimeoutSec=%s", timeout_value);
- if (r < 0)
- return log_error_errno(r, "Failed to write device drop-in: %m");
+ if (timeout_value) {
+ r = write_drop_in_format(arg_dest, unit, 90, "device-timeout",
+ "# Automatically generated by systemd-cryptsetup-generator \n\n"
+ "[Unit]\nJobRunningTimeoutSec=%s", timeout_value);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write device drop-in: %m");
+ }
} else
fprintf(f, "Requires=%1$s\n", unit);
} else {
if (!escaped_path)
return log_oom();
- fprintf(f, "RequiresMountsFor=%s\n", escaped_path);
+ fprintf(f, "%s=%s\n", canfail ? "WantsMountsFor" : "RequiresMountsFor", escaped_path);
}
return 0;
if (key_file && !keydev) {
r = print_dependencies(f, key_file,
keyfile_timeout_value,
- /* canfail= */ keyfile_can_timeout > 0);
+ /* canfail= */ keyfile_can_timeout > 0 || nofail);
if (r < 0)
return r;
}
/* Check if a header option was specified */
if (detached_header > 0 && !headerdev) {
r = print_dependencies(f, header_path,
- NULL,
- /* canfail= */ false); /* header is always necessary */
+ /* timeout_value= */ NULL,
+ /* canfail= */ nofail);
if (r < 0)
return r;
}
cryptsetup_start_and_check() {
local expect_fail=0
+ local umount_header_and_key=0
local ec volume unit
if [[ "${1:?}" == "-f" ]]; then
shift
fi
+ if [[ "${1:?}" == "-u" ]]; then
+ umount_header_and_key=1
+ shift
+ fi
+
for volume in "$@"; do
unit="systemd-cryptsetup@$volume.service"
return 1
fi
+ if [[ "$umount_header_and_key" -ne 0 ]]; then
+ umount "$TMPFS_DETACHED_KEYFILE"
+ umount "$TMPFS_DETACHED_HEADER"
+ udevadm settle --timeout=30
+ fi
+
systemctl status "$unit"
test -e "/dev/mapper/$volume"
systemctl stop "$unit"
mount "/dev/disk/by-partlabel/keyfile_store" /mnt
cp "$IMAGE_DETACHED_KEYFILE2" /mnt/keyfile
umount /mnt
+
+# Also copy the key and header on a tmpfs that we will umount after unlocking
+TMPFS_DETACHED_KEYFILE="$(mktemp -d)"
+TMPFS_DETACHED_HEADER="$(mktemp -d)"
+mount -t tmpfs -o size=32M tmpfs "$TMPFS_DETACHED_KEYFILE"
+mount -t tmpfs -o size=32M tmpfs "$TMPFS_DETACHED_HEADER"
+cp "$IMAGE_DETACHED_KEYFILE" "$TMPFS_DETACHED_KEYFILE/keyfile"
+cp "$IMAGE_DETACHED_HEADER" "$TMPFS_DETACHED_HEADER/header"
+
udevadm settle --timeout=30
# Prepare our test crypttab
detached_slot0 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER
detached_slot1 $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER,key-slot=8
detached_slot_fail $IMAGE_DETACHED $IMAGE_DETACHED_KEYFILE2 headless=1,header=$IMAGE_DETACHED_HEADER,key-slot=0
+detached_nofail $IMAGE_DETACHED $TMPFS_DETACHED_KEYFILE/keyfile headless=1,header=$TMPFS_DETACHED_HEADER/header,keyfile-offset=32,keyfile-size=16,nofail
EOF
# Temporarily drop luks.name=/luks.uuid= from the kernel command line, as it makes
cryptsetup_start_and_check -f detached_fail{0..4}
cryptsetup_start_and_check detached_slot{0..1}
cryptsetup_start_and_check -f detached_slot_fail
+cryptsetup_start_and_check -u detached_nofail
touch /testok