Blame SOURCES/rear-bz1832394.patch

b9f7b3
diff --git a/doc/user-guide/06-layout-configuration.adoc b/doc/user-guide/06-layout-configuration.adoc
b9f7b3
index f59384db..88ba0420 100644
b9f7b3
--- a/doc/user-guide/06-layout-configuration.adoc
b9f7b3
+++ b/doc/user-guide/06-layout-configuration.adoc
b9f7b3
@@ -630,7 +630,7 @@ lvmvol <volume_group> <name> <size(bytes)> <layout> [key:value ...]
b9f7b3
 
b9f7b3
 === LUKS Devices ===
b9f7b3
 ----------------------------------
b9f7b3
-crypt /dev/mapper/<name> <device> [cipher=<cipher>] [key_size=<key size>] [hash=<hash function>] [uuid=<uuid>] [keyfile=<keyfile>] [password=<password>]
b9f7b3
+crypt /dev/mapper/<name> <device> [type=<type>] [cipher=<cipher>] [key_size=<key size>] [hash=<hash function>] [uuid=<uuid>] [keyfile=<keyfile>] [password=<password>]
b9f7b3
 ----------------------------------
b9f7b3
 
b9f7b3
 === DRBD ===
b9f7b3
diff --git a/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh b/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh
b9f7b3
index 05279bc8..0c662f67 100644
b9f7b3
--- a/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh
b9f7b3
+++ b/usr/share/rear/layout/prepare/GNU/Linux/160_include_luks_code.sh
b9f7b3
@@ -1,35 +1,75 @@
b9f7b3
+
b9f7b3
 # Code to recreate and/or open LUKS volumes.
b9f7b3
 
b9f7b3
 create_crypt() {
b9f7b3
+    # See the create_device() function in lib/layout-functions.sh what "device type" means:
b9f7b3
+    local device_type="$1"
b9f7b3
+    if ! grep -q "^crypt $device_type " "$LAYOUT_FILE" ; then
b9f7b3
+        LogPrintError "Skip recreating LUKS volume $device_type (no 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the create_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
+    
b9f7b3
     local crypt target_device source_device options
b9f7b3
-    read crypt target_device source_device options < <(grep "^crypt $1 " "$LAYOUT_FILE")
b9f7b3
+    local mapping_name option key value
b9f7b3
+    local cryptsetup_options="" keyfile="" password=""
b9f7b3
 
b9f7b3
-    local target_name=${target_device#/dev/mapper/}
b9f7b3
+    read crypt target_device source_device options < <( grep "^crypt $device_type " "$LAYOUT_FILE" )
b9f7b3
+
b9f7b3
+    # Careful! One cannot 'test -b $source_device' here at the time when this code is run
b9f7b3
+    # because the source device is usually a disk partition block device like /dev/sda2
b9f7b3
+    # but disk partition block devices usually do not yet exist (in particular not on a new clean disk)
b9f7b3
+    # because partitions are actually created later when the diskrestore.sh script is run
b9f7b3
+    # but not here when this code is run which only generates the diskrestore.sh script:
b9f7b3
+    if ! test $source_device ; then
b9f7b3
+        LogPrintError "Skip recreating LUKS volume $device_type: No source device (see the 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the create_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
+
b9f7b3
+    mapping_name=${target_device#/dev/mapper/}
b9f7b3
+    if ! test $mapping_name ; then
b9f7b3
+        LogPrintError "Skip recreating LUKS volume $device_type on $source_device: No /dev/mapper/... mapping name (see the 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the create_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
 
b9f7b3
-    local cryptsetup_options="" keyfile="" password=""
b9f7b3
-    local option key value
b9f7b3
     for option in $options ; do
b9f7b3
-        key=${option%=*}
b9f7b3
+        # $option is of the form keyword=value and
b9f7b3
+        # we assume keyword has no '=' character but value could be anything that may have a '=' character
b9f7b3
+        # so we split keyword=value at the leftmost '=' character so that
b9f7b3
+        # e.g. keyword=foo=bar gets split into key="keyword" and value="foo=bar":
b9f7b3
+        key=${option%%=*}
b9f7b3
         value=${option#*=}
b9f7b3
-
b9f7b3
+        # The "cryptseup luksFormat" command does not require any of the type, cipher, key-size, hash, uuid option values
b9f7b3
+        # because if omitted a cryptseup default value is used so we treat those values as optional.
b9f7b3
+        # Using plain test to ensure the value is a single non empty and non blank word
b9f7b3
+        # without quoting because test " " would return zero exit code
b9f7b3
+        # cf. "Beware of the emptiness" in https://github.com/rear/rear/wiki/Coding-Style
b9f7b3
         case "$key" in
b9f7b3
-            cipher)
b9f7b3
-                cryptsetup_options+=" --cipher $value"
b9f7b3
+            (type)
b9f7b3
+                test $value && cryptsetup_options+=" --type $value"
b9f7b3
+                ;;
b9f7b3
+            (cipher)
b9f7b3
+                test $value && cryptsetup_options+=" --cipher $value"
b9f7b3
+                ;;
b9f7b3
+            (key_size)
b9f7b3
+                test $value && cryptsetup_options+=" --key-size $value"
b9f7b3
                 ;;
b9f7b3
-            key_size)
b9f7b3
-                cryptsetup_options+=" --key-size $value"
b9f7b3
+            (hash)
b9f7b3
+                test $value && cryptsetup_options+=" --hash $value"
b9f7b3
                 ;;
b9f7b3
-            hash)
b9f7b3
-                cryptsetup_options+=" --hash $value"
b9f7b3
+            (uuid)
b9f7b3
+                test $value && cryptsetup_options+=" --uuid $value"
b9f7b3
                 ;;
b9f7b3
-            uuid)
b9f7b3
-                cryptsetup_options+=" --uuid $value"
b9f7b3
+            (keyfile)
b9f7b3
+                test $value && keyfile=$value
b9f7b3
                 ;;
b9f7b3
-            keyfile)
b9f7b3
-                keyfile=$value
b9f7b3
+            (password)
b9f7b3
+                test $value && password=$value
b9f7b3
                 ;;
b9f7b3
-            password)
b9f7b3
-                password=$value
b9f7b3
+            (*)
b9f7b3
+                LogPrintError "Skipping unsupported LUKS cryptsetup option '$key' in 'crypt $target_device $source_device' entry in $LAYOUT_FILE"
b9f7b3
                 ;;
b9f7b3
         esac
b9f7b3
     done
b9f7b3
@@ -37,26 +77,25 @@ create_crypt() {
b9f7b3
     cryptsetup_options+=" $LUKS_CRYPTSETUP_OPTIONS"
b9f7b3
 
b9f7b3
     (
b9f7b3
-    echo "Log \"Creating LUKS device $target_name on $source_device\""
b9f7b3
+    echo "LogPrint \"Creating LUKS volume $mapping_name on $source_device\""
b9f7b3
     if [ -n "$keyfile" ] ; then
b9f7b3
         # Assign a temporary keyfile at this stage so that original keyfiles do not leak onto the rescue medium.
b9f7b3
         # The original keyfile will be restored from the backup and then re-assigned to the LUKS device in the
b9f7b3
         # 'finalize' stage.
b9f7b3
         # The scheme for generating a temporary keyfile path must be the same here and in the 'finalize' stage.
b9f7b3
-        keyfile="${TMPDIR:-/tmp}/LUKS-keyfile-$target_name"
b9f7b3
+        keyfile="$TMP_DIR/LUKS-keyfile-$mapping_name"
b9f7b3
         dd bs=512 count=4 if=/dev/urandom of="$keyfile"
b9f7b3
         chmod u=rw,go=- "$keyfile"
b9f7b3
-
b9f7b3
         echo "cryptsetup luksFormat --batch-mode $cryptsetup_options $source_device $keyfile"
b9f7b3
-        echo "cryptsetup luksOpen --key-file $keyfile $source_device $target_name"
b9f7b3
+        echo "cryptsetup luksOpen --key-file $keyfile $source_device $mapping_name"
b9f7b3
     elif [ -n "$password" ] ; then
b9f7b3
         echo "echo \"$password\" | cryptsetup luksFormat --batch-mode $cryptsetup_options $source_device"
b9f7b3
-        echo "echo \"$password\" | cryptsetup luksOpen $source_device $target_name"
b9f7b3
+        echo "echo \"$password\" | cryptsetup luksOpen $source_device $mapping_name"
b9f7b3
     else
b9f7b3
-        echo "LogPrint \"Please enter the password for LUKS device $target_name ($source_device):\""
b9f7b3
+        echo "LogUserOutput \"Set the password for LUKS volume $mapping_name (for 'cryptsetup luksFormat' on $source_device):\""
b9f7b3
         echo "cryptsetup luksFormat --batch-mode $cryptsetup_options $source_device"
b9f7b3
-        echo "LogPrint \"Please re-enter the password for LUKS device $target_name ($source_device):\""
b9f7b3
-        echo "cryptsetup luksOpen $source_device $target_name"
b9f7b3
+        echo "LogUserOutput \"Enter the password for LUKS volume $mapping_name (for 'cryptsetup luksOpen' on $source_device):\""
b9f7b3
+        echo "cryptsetup luksOpen $source_device $mapping_name"
b9f7b3
     fi
b9f7b3
     echo ""
b9f7b3
     ) >> "$LAYOUT_CODE"
b9f7b3
@@ -64,38 +103,61 @@ create_crypt() {
b9f7b3
 
b9f7b3
 # Function open_crypt() is meant to be used by the 'mountonly' workflow
b9f7b3
 open_crypt() {
b9f7b3
+    # See the do_mount_device() function in lib/layout-functions.sh what "device type" means:
b9f7b3
+    local device_type="$1"
b9f7b3
+    if ! grep -q "^crypt $device_type " "$LAYOUT_FILE" ; then
b9f7b3
+        LogPrintError "Skip opening LUKS volume $device_type (no 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the do_mount_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
+
b9f7b3
     local crypt target_device source_device options
b9f7b3
-    read crypt target_device source_device options < <(grep "^crypt $1 " "$LAYOUT_FILE")
b9f7b3
+    local mapping_name option key value
b9f7b3
+    local cryptsetup_options="" keyfile="" password=""
b9f7b3
 
b9f7b3
-    local target_name=${target_device#/dev/mapper/}
b9f7b3
+    read crypt target_device source_device options < <( grep "^crypt $device_type " "$LAYOUT_FILE" )
b9f7b3
+
b9f7b3
+    if ! test -b "$source_device" ; then
b9f7b3
+        LogPrintError "Skip opening LUKS volume $device_type on device '$source_device' that is no block device (see the 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the do_mount_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
+
b9f7b3
+    mapping_name=${target_device#/dev/mapper/}
b9f7b3
+    if ! test $mapping_name ; then
b9f7b3
+        LogPrintError "Skip opening LUKS volume $device_type on $source_device: No /dev/mapper/... mapping name (see the 'crypt $device_type' entry in $LAYOUT_FILE)"
b9f7b3
+        # FIXME: The return code is ignored in the do_mount_device() function in lib/layout-functions.sh:
b9f7b3
+        return 1
b9f7b3
+    fi
b9f7b3
 
b9f7b3
-    local cryptsetup_options="" keyfile="" password=""
b9f7b3
-    local option key value
b9f7b3
     for option in $options ; do
b9f7b3
-        key=${option%=*}
b9f7b3
+        # $option is of the form keyword=value and
b9f7b3
+        # we assume keyword has no '=' character but value could be anything that may have a '=' character
b9f7b3
+        # so we split keyword=value at the leftmost '=' character so that
b9f7b3
+        # e.g. keyword=foo=bar gets split into key="keyword" and value="foo=bar":
b9f7b3
+        key=${option%%=*}
b9f7b3
         value=${option#*=}
b9f7b3
-
b9f7b3
         case "$key" in
b9f7b3
-            keyfile)
b9f7b3
-                keyfile=$value
b9f7b3
+            (keyfile)
b9f7b3
+                test $value && keyfile=$value
b9f7b3
                 ;;
b9f7b3
-            password)
b9f7b3
-                password=$value
b9f7b3
+            (password)
b9f7b3
+                test $value && password=$value
b9f7b3
                 ;;
b9f7b3
         esac
b9f7b3
     done
b9f7b3
 
b9f7b3
     (
b9f7b3
-    echo "Log \"Opening LUKS device $target_name on $source_device\""
b9f7b3
+    echo "LogPrint \"Opening LUKS volume $mapping_name on $source_device\""
b9f7b3
     if [ -n "$keyfile" ] ; then
b9f7b3
         # During a 'mountonly' workflow, the original keyfile is supposed to be
b9f7b3
         # available at this point.
b9f7b3
-        echo "cryptsetup luksOpen --key-file $keyfile $source_device $target_name"
b9f7b3
+        echo "cryptsetup luksOpen --key-file $keyfile $source_device $mapping_name"
b9f7b3
     elif [ -n "$password" ] ; then
b9f7b3
-        echo "echo \"$password\" | cryptsetup luksOpen $source_device $target_name"
b9f7b3
+        echo "echo \"$password\" | cryptsetup luksOpen $source_device $mapping_name"
b9f7b3
     else
b9f7b3
-        echo "LogPrint \"Please enter the password for LUKS device $target_name ($source_device):\""
b9f7b3
-        echo "cryptsetup luksOpen $source_device $target_name"
b9f7b3
+        echo "LogUserOutput \"Enter the password for LUKS volume $mapping_name (for 'cryptsetup luksOpen' on $source_device):\""
b9f7b3
+        echo "cryptsetup luksOpen $source_device $mapping_name"
b9f7b3
     fi
b9f7b3
     echo ""
b9f7b3
     ) >> "$LAYOUT_CODE"
b9f7b3
diff --git a/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh b/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh
b9f7b3
index c1e1cfd5..afeabf6a 100644
b9f7b3
--- a/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh
b9f7b3
+++ b/usr/share/rear/layout/save/GNU/Linux/260_crypt_layout.sh
b9f7b3
@@ -9,6 +9,8 @@ Log "Saving Encrypted volumes."
b9f7b3
 REQUIRED_PROGS+=( cryptsetup dmsetup )
b9f7b3
 COPY_AS_IS+=( /usr/share/cracklib/\* /etc/security/pwquality.conf )
b9f7b3
 
b9f7b3
+local invalid_cryptsetup_option_value="no"
b9f7b3
+
b9f7b3
 while read target_name junk ; do
b9f7b3
     # find the target device we're mapping
b9f7b3
     if ! [ -e /dev/mapper/$target_name ] ; then
b9f7b3
@@ -30,29 +32,96 @@ while read target_name junk ; do
b9f7b3
         source_device="$(get_device_name ${slave##*/})"
b9f7b3
     done
b9f7b3
 
b9f7b3
-    if ! cryptsetup isLuks $source_device >/dev/null 2>&1; then
b9f7b3
+    if ! blkid -p -o export $source_device >$TMP_DIR/blkid.output ; then
b9f7b3
+        LogPrintError "Error: Cannot get attributes for $target_name ('blkid -p -o export $source_device' failed)"
b9f7b3
         continue
b9f7b3
     fi
b9f7b3
 
b9f7b3
-    # gather crypt information
b9f7b3
-    cipher=$(cryptsetup luksDump $source_device | grep "Cipher name" | sed -r 's/^.+:\s*(.+)$/\1/')
b9f7b3
-    mode=$(cryptsetup luksDump $source_device | grep "Cipher mode" | cut -d: -f2- | awk '{printf("%s",$1)};')
b9f7b3
-    key_size=$(cryptsetup luksDump $source_device | grep "MK bits" | sed -r 's/^.+:\s*(.+)$/\1/')
b9f7b3
-    hash=$(cryptsetup luksDump $source_device | grep "Hash spec" | sed -r 's/^.+:\s*(.+)$/\1/')
b9f7b3
-    uuid=$(cryptsetup luksDump $source_device | grep "UUID" | sed -r 's/^.+:\s*(.+)$/\1/')
b9f7b3
-    keyfile_option=$([ -f /etc/crypttab ] && awk '$1 == "'"$target_name"'" && $3 != "none" && $3 != "-" && $3 != "" { print "keyfile=" $3; }' /etc/crypttab)
b9f7b3
+    if ! grep -q "TYPE=crypto_LUKS" $TMP_DIR/blkid.output ; then
b9f7b3
+        Log "Skipping $target_name (no 'TYPE=crypto_LUKS' in 'blkid -p -o export $source_device' output)"
b9f7b3
+        continue
b9f7b3
+    fi
b9f7b3
 
b9f7b3
-    # LUKS version 2 is not yet suppported, see https://github.com/rear/rear/issues/2204
b9f7b3
-    # When LUKS version 2 is used the above code fails at least to determine the hash value
b9f7b3
-    # so we use an empty hash value as a simple test if gathering crypt information was successful:
b9f7b3
-    test "$hash" || Error "No hash value for LUKS device '$target_name' at '$source_device' (only LUKS version 1 is supported)"
b9f7b3
+    # Detect LUKS version:
b9f7b3
+    # Remove all non-digits in particular to avoid leading or trailing spaces in the version string
b9f7b3
+    # cf. "Beware of the emptiness" in https://github.com/rear/rear/wiki/Coding-Style
b9f7b3
+    # that could happen if the blkid output contains "VERSION = 2" so that 'cut -d= -f2' results " 2".
b9f7b3
+    version=$( grep "VERSION" $TMP_DIR/blkid.output | cut -d= -f2 | tr -c -d '[:digit:]' )
b9f7b3
+    if ! test "$version" = "1" -o "$version" = "2" ; then
b9f7b3
+        LogPrintError "Error: Unsupported LUKS version for $target_name ('blkid -p -o export $source_device' shows 'VERSION=$version')"
b9f7b3
+        continue
b9f7b3
+    fi
b9f7b3
+    luks_type=luks$version
b9f7b3
 
b9f7b3
-    echo "crypt /dev/mapper/$target_name $source_device cipher=$cipher-$mode key_size=$key_size hash=$hash uuid=$uuid $keyfile_option" >> $DISKLAYOUT_FILE
b9f7b3
-done < <( dmsetup ls --target crypt )
b9f7b3
+    # Gather crypt information:
b9f7b3
+    if ! cryptsetup luksDump $source_device >$TMP_DIR/cryptsetup.luksDump ; then
b9f7b3
+        LogPrintError "Error: Cannot get LUKS$version values for $target_name ('cryptsetup luksDump $source_device' failed)"
b9f7b3
+        continue
b9f7b3
+    fi
b9f7b3
+    uuid=$( grep "UUID" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+    keyfile_option=$( [ -f /etc/crypttab ] && awk '$1 == "'"$target_name"'" && $3 != "none" && $3 != "-" && $3 != "" { print "keyfile=" $3; }' /etc/crypttab )
b9f7b3
+    if test $luks_type = "luks1" ; then
b9f7b3
+        cipher_name=$( grep "Cipher name" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+        cipher_mode=$( grep "Cipher mode" $TMP_DIR/cryptsetup.luksDump | cut -d: -f2- | awk '{printf("%s",$1)};' )
b9f7b3
+        cipher=$cipher_name-$cipher_mode
b9f7b3
+        key_size=$( grep "MK bits" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+        hash=$( grep "Hash spec" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+    elif test $luks_type = "luks2" ; then
b9f7b3
+        cipher=$( grep "cipher:" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+        # More than one keyslot may be defined - use key_size from the first slot.
b9f7b3
+        # Depending on the version the "cryptsetup luksDump" command outputs the key_size value
b9f7b3
+        # as a line like
b9f7b3
+        #         Key:        512 bits
b9f7b3
+        # and/or as a line like
b9f7b3
+        #         Cipher key: 512 bits
b9f7b3
+        # cf. https://github.com/rear/rear/pull/2504#issuecomment-718729198 and subsequent comments
b9f7b3
+        # so we grep for both lines but use only the first match from the first slot:
b9f7b3
+        key_size=$( egrep -m 1 "Key:|Cipher key:" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+) bits$/\1/' )
b9f7b3
+        hash=$( grep "Hash" $TMP_DIR/cryptsetup.luksDump | sed -r 's/^.+:\s*(.+)$/\1/' )
b9f7b3
+    fi
b9f7b3
 
b9f7b3
-# cryptsetup is required in the recovery system if disklayout.conf contains at least one 'crypt' entry
b9f7b3
-# see the create_crypt function in layout/prepare/GNU/Linux/160_include_luks_code.sh
b9f7b3
-# what program calls are written to diskrestore.sh
b9f7b3
-# cf. https://github.com/rear/rear/issues/1963
b9f7b3
-grep -q '^crypt ' $DISKLAYOUT_FILE && REQUIRED_PROGS+=( cryptsetup ) || true
b9f7b3
+    # Basic checks that the cipher key_size hash uuid values exist
b9f7b3
+    # cf. https://github.com/rear/rear/pull/2504#issuecomment-718729198
b9f7b3
+    # because some values are needed during "rear recover"
b9f7b3
+    # to set cryptsetup options in layout/prepare/GNU/Linux/160_include_luks_code.sh
b9f7b3
+    # and it seems cryptsetup fails when options with empty values are specified
b9f7b3
+    # cf. https://github.com/rear/rear/pull/2504#issuecomment-719479724
b9f7b3
+    # For example a LUKS1 crypt entry in disklayout.conf looks like
b9f7b3
+    # crypt /dev/mapper/luks1test /dev/sda7 type=luks1 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=1b4198c9-d9b0-4c57-b9a3-3433e391e706 
b9f7b3
+    # and a LUKS1 crypt entry in disklayout.conf looks like
b9f7b3
+    # crypt /dev/mapper/luks2test /dev/sda8 type=luks2 cipher=aes-xts-plain64 key_size=256 hash=sha256 uuid=3e874a28-7415-4f8c-9757-b3f28a96c4d2 
b9f7b3
+    # Only the keyfile_option value is optional and the luks_type value is already tested above.
b9f7b3
+    # Using plain test to ensure a value is a single non empty and non blank word
b9f7b3
+    # without quoting because test " " would return zero exit code
b9f7b3
+    # cf. "Beware of the emptiness" in https://github.com/rear/rear/wiki/Coding-Style
b9f7b3
+    # Do not error out instantly here but only report errors here so the user can see all messages
b9f7b3
+    # and actually error out at the end of this script if there was one actually invalid value:
b9f7b3
+    if ! test $cipher ; then
b9f7b3
+        LogPrint "No 'cipher' value for LUKS$version volume $target_name in $source_device"
b9f7b3
+    fi
b9f7b3
+    if test $key_size ; then
b9f7b3
+        if ! is_positive_integer $key_size ; then
b9f7b3
+            LogPrintError "Error: 'key_size=$key_size' is no positive integer for LUKS$version volume $target_name in $source_device"
b9f7b3
+            invalid_cryptsetup_option_value="yes"
b9f7b3
+        fi
b9f7b3
+    else
b9f7b3
+        LogPrint "No 'key_size' value for LUKS$version volume $target_name in $source_device"
b9f7b3
+    fi
b9f7b3
+    if ! test $hash ; then
b9f7b3
+        LogPrint "No 'hash' value for LUKS$version volume $target_name in $source_device"
b9f7b3
+    fi
b9f7b3
+    if ! test $uuid ; then
b9f7b3
+        # Report a missig uuid value as an error to have the user informed
b9f7b3
+        # but do not error out here because things can be fixed manually during "rear recover"
b9f7b3
+        # cf. https://github.com/rear/rear/pull/2506#issuecomment-721757810
b9f7b3
+        # and https://github.com/rear/rear/pull/2506#issuecomment-722315498
b9f7b3
+        # and https://github.com/rear/rear/issues/2509
b9f7b3
+        LogPrintError "Error: No 'uuid' value for LUKS$version volume $target_name in $source_device (mounting it or booting the recreated system may fail)"
b9f7b3
+    fi
b9f7b3
+
b9f7b3
+    echo "crypt /dev/mapper/$target_name $source_device type=$luks_type cipher=$cipher key_size=$key_size hash=$hash uuid=$uuid $keyfile_option" >> $DISKLAYOUT_FILE
b9f7b3
+
b9f7b3
+done < <( dmsetup ls --target crypt )
b9f7b3
 
b9f7b3
+# Let this script return successfully when invalid_cryptsetup_option_value is not true:
b9f7b3
+is_true $invalid_cryptsetup_option_value && Error "Invalid or empty LUKS cryptsetup option value(s) in $DISKLAYOUT_FILE" || true