22.03.2018 18:59, Andrey Jr. Melnikov пишет:
> artiom <[email protected]> wrote:
>> Честно говоря, думал, что на такой вопрос я получу ответ в виде
>> "погугли", но если возможно (и появится бэкпорт), я только "за".
>> Вопрос, где открыть баг?
> 
> reportbug initramfs-tools
> 
$ dpkg -S /usr/share/initramfs-tools/hooks/cryptroot

cryptsetup: /usr/share/initramfs-tools/hooks/cryptroot

Наверное, тогда cryptsetup?

>> И zfs не входит в поставку Linux, прокатит ли?
> А это кто его знает.
> 
На всякий случай, приложу хук, скрипт и дифы.
diff /usr/share/initramfs-tools/scripts/local-top/cryptroot cryptroot

35a36,37
> 	elif [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then
> 		usplash_write "TEXT-URGENT $@"
101a104,105
> 			elif [ ${cryptsource#ID=} != $cryptsource ]; then
> 				cryptsource="/dev/disk/by-id/${cryptsource#ID=}"
182c186
< 	local opts count cryptopen cryptremove NEWROOT
---
> 	local opts count cryptopen cryptremove NEWROOT is_luks
183a188
> 	is_luks=0
199c204
< 		cryptkey="Please unlock disk $diskname: "
---
> 		cryptkey="1Please unlock disk $diskname: "
244a250,252
> 		if [ -x /sbin/usplash_write ]; then
> 			/sbin/usplash_write "TIMEOUT ${slumber}" || true
> 		fi
262a271,273
> 		if [ -x /sbin/usplash_write ]; then
> 			/sbin/usplash_write "TIMEOUT 15" || true
> 		fi
291a303
> 		is_luks=1
304a317,337
> 		if [ $count -gt 1 ]; then
> 			/bin/sleep 3
> 		fi
> 
> 		if [ -z "$cryptkeyscript" -a "$is_luks" -eq "1" ]; then
> 			cryptkey="Unlocking the disk $cryptsource ($crypttarget)\nEnter passphrase: "
> 			if [ -x /bin/plymouth ] && plymouth --ping; then
> 				cryptkeyscript="plymouth ask-for-password --prompt"
> 				cryptkey=$(echo -e "$cryptkey")
> 			else
> 				cryptkeyscript="/lib/cryptsetup/askpass"
> 			fi
> 		fi
> 
> 		if [ -n "$CACHED_PASSWORD" ]; then
> 			if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
> 			     echo -n "$CACHED_PASSWORD" | $cryptopen 2>/dev/null; then
> 				unset CACHED_PASSWORD
> 			fi
> 		fi
> 
307c340,341
< 		if [ ! -e "$NEWROOT" ]; then
---
> 		if [ -z "$CACHED_PASSWORD" ]; then
> 			CACHED_PASSWORD="`$cryptkeyscript \"$cryptkey\"`"
309,310c343,345
< 			     $cryptkeyscript "$cryptkey" | $cryptopen; then
< 				message "cryptsetup ($crypttarget): cryptsetup failed, bad password or options?"
---
> 			     echo -n "$CACHED_PASSWORD" | $cryptopen; then
> 				message "cryptsetup: cryptsetup failed, bad password or options?"
> 				unset CACHED_PASSWORD
355a391
> 			unset CACHED_PASSWORD
362a399,401
> 		
> 		export CACHED_PASSWORD
> 		
378a418,424
> exit_script()
> {
> 	CACHED_PASSWORD="`dd bs=512 if=/dev/random count=1 2>/dev/null `"
> 	unset CACHED_PASSWORD
> 	exit $1
> }
> 
425c471
< exit 0
---
> exit_script 0
diff /usr/share/initramfs-tools/hooks/cryptroot cryptroot

45a46,51
>                       elif [ "$type" = "zfs" ]; then
>                               zpool="$(echo "$device"|sed 's#^/dev/zvol/##;s#\([^/]*\).*#\1#')"
>                               for ss in $(zpool list -Pv "$zpool"); do
>                                       cdev=$(canonical_device "$ss" 2>/dev/null) || continue
>                                       devices="${devices:+$devices }$cdev"
>                               done || return 0
375c381
< 	if [ "UUID=${source#UUID=}" = "$source" -a ! -b "/dev/disk/by-uuid/${source#UUID=}" ] || [ "UUID=${source#UUID=}" != "$source" -a ! -b "$source" ]; then
---
> 	if [ "UUID=${source#UUID=}" = "$source" -a ! \( -b "/dev/disk/by-uuid/${source#UUID=}" -o -b "/dev/disk/by-partuuid/${source#UUID=}" \) ] || [ "UUID=${source#UUID=}" != "$source" -a ! -b "$source" ]; then
#!/bin/sh

PREREQ=""

prereqs()
{
        echo "$PREREQ"
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

. /usr/share/initramfs-tools/hook-functions

# get_fs_devices() - determine source device(s) of mount point from /etc/fstab
#
# expected arguments:
# * fstab mount point (full path)
#
# This function searches for the first entry from /etc/fstab which has the
# given mountpoint set. It returns the canonical_device() of corresponding
# source device (first field in /etc/fstab entry).
# In case of btrfs, canoncial_device() of all btrfs source devices (possibly
# more than one) are returned.
#
get_fs_devices() {
        local device mount type options dump pass
        local wantmount="$1"

        if [ ! -r /etc/fstab ]; then
                return 1
        fi

        grep -s '^[^#]' /etc/fstab | \
        while read device mount type options dump pass; do
                if [ "$mount" = "$wantmount" ]; then
                        local devices
                        if [ "$type" = "btrfs" ]; then
                                for dev in $(btrfs filesystem show 
$(canonical_device "$device" --no-simplify) 2>/dev/null | sed -r -e 's/.*devid 
.+ path (.+)/\1/;tx;d;:x') ; do
                                        devices="${devices:+$devices 
}$(canonical_device "$dev")"
                                done
                      elif [ "$type" = "zfs" ]; then
                              zpool="$(echo "$device"|sed 
's#^/dev/zvol/##;s#\([^/]*\).*#\1#')"
                              for ss in $(zpool list -Pv "$zpool"); do
                                      cdev=$(canonical_device "$ss" 
2>/dev/null) || continue
                                      devices="${devices:+$devices }$cdev"
                              done || return 0
                        else
                                devices=$(canonical_device "$device") || return 0
                        fi
                        printf '%s' "$devices"
                        return
                fi
        done
}

# get_resume_devices() - determine devices used for system suspend/hibernate
#
# expected arguments:
# * none
#
# This function searches well known places for devices that are used for system
# suspension and/or hibernation. It returns canonical_device() of any detected
# devices and prints a warning if more than one device is detected.
#
get_resume_devices() {
        local device opt count dupe candidates devices derived
        candidates=""

        # First, get a list of potential resume devices

        # uswsusp
        if [ -e /etc/uswsusp.conf ]; then
                device=$(sed -rn 's/^resume 
device[[:space:]]*[:=][[:space:]]*// p' /etc/uswsusp.conf)
                if [ -n "$device" ]; then
                        candidates="${candidates:+$candidates }$device"
                fi
        fi

        # uswsusp - again...
        if [ -e /etc/suspend.conf ]; then
                device=$(sed -rn 's/^resume 
device[[:space:]]*[:=][[:space:]]*// p' /etc/suspend.conf)
                if [ -n "$device" ]; then
                        candidates="${candidates:+$candidates }$device"
                fi
        fi

        # regular swsusp
        for opt in $(cat /proc/cmdline); do
                case $opt in
                        resume=*)
                                device="${opt#resume=}"
                                candidates="${candidates:+$candidates }$device"
                                ;;
                esac
        done

        # initramfs-tools >=0.129
        device="${RESUME:-auto}"
        if [ "$device" != none ]; then
                if [ "$device" = auto ]; then
                        # next line from /usr/share/initramfs-tools/hooks/resume
                        device="$(grep ^/dev/ /proc/swaps | sort -rnk3 | head 
-n 1 | cut -d " " -f 1)"
                        if [ -n "$device" ]; then
                                device="UUID=$(blkid -s UUID -o value "$device" 
|| true)"
                        fi
                fi
                candidates="${candidates:+$candidates }$device"
        fi

        # Now check the sanity of all candidates
        devices=""
        count=0
        for device in $candidates; do
                # Remove quotes around device candidate
                device=$(printf '%s' "$device" | sed -r -e 's/^"(.*)"\s*$/\1/' 
-e "s/^'(.*)'\s*$/\1/")

                # Weed out clever defaults
                if [ "$device" = "<path_to_resume_device_file>" ]; then
                        continue
                fi

                # Detect devices required by decrypt_derived
                derived=$(get_derived_device "$device")
                if [ -n "$derived" ]; then
                        devices="${devices:+$devices }$derived"
                fi

                device=$(canonical_device "$device") || return 0

                # Weed out duplicates
                dupe=0
                for opt in $devices; do
                        if [ "$device" = "$opt" ]; then
                                dupe=1
                        fi
                done
                if [ $dupe -eq 1 ]; then
                        continue
                fi

                # This device seems ok
                devices="${devices:+$devices }$device"
                count=$(( $count + 1 ))
        done

        if [ $count -gt 1 ]; then
                echo "cryptsetup: WARNING: found more than one resume device 
candidate:" >&2
                for device in $devices; do
                        echo "                     $device" >&2
                done
        fi

        if [ $count -gt 0 ]; then
                printf '%s' "$devices"
        fi

        return 0
}

# get_initramfs_devices() - determine devices with explicit 'initramfs' option
#
# expected arguments:
# * none
#
# This function processes entries from /etc/crypttab with the 'initramfs'
# option set. For each processed device, potential get_derived_device()
# devices are determined. The canonical_device() of each detected device
# is returned.
#
get_initramfs_devices() {
        local device opt count dupe target source key options candidates 
devices derived

        candidates="$(grep -s '^[^#]' /etc/crypttab | \
        while read target source key options; do
                if printf '%s' "$options" | grep -Eq "^(.*,)?initramfs(,.*)?$"; 
then
                        echo " /dev/mapper/$target"
                fi
        done;)"

        devices=""
        count=0
        for device in $candidates; do
                # Detect devices required by decrypt_derived
                derived=$(get_derived_device "$device")
                if [ -n "$derived" ]; then
                        devices="${devices:+$devices }$derived"
                fi

                device=$(canonical_device "$device") || return 0

                # Weed out duplicates
                dupe=0
                for opt in $devices; do
                        if [ "$device" = "$opt" ]; then
                                dupe=1
                        fi
                done
                if [ $dupe -eq 1 ]; then
                        continue
                fi

                # This device seems ok
                devices="${devices:+$devices }$device"
                count=$(( $count + 1 ))
        done

        if [ $count -gt 0 ]; then
                printf '%s' "$devices"
        fi

        return 0
}

# get_derived_device() - determine dependency devices for decrypt_derived
#
# expected arguments:
# * crypttab target device name (either <name> or /dev/mapper/<name>)
#
# This function takes a target device name and checks whether this device has
# the decrypt_derived keyscript set in /etc/crypttab. If true, the dependency
# device required for the decrypt_derived keyscript is detected and its
# canonical_device() returned if it's not listed in $rootdevs.
#
get_derived_device() {
        local device derived
        device="$1"

        derived="$( awk -vtarget="${device#/dev/mapper/}" \
                '$1 == target && $4 ~ 
/^(.*,)?keyscript=([^,]*\/)?decrypt_derived(,.*)?$/ {print $3; exit}' \
                /etc/crypttab )"
        if [ -n "$derived" ]; then
                if node_is_in_crypttab "$derived"; then
                        derived=$(canonical_device "/dev/mapper/$derived") || 
return 0
                        if ! printf '%s' "$rootdevs" | tr ' ' '\n' | grep -Fxq 
"$derived"; then
                                printf '%s' "$derived"
                        fi
                else
                        echo "cryptsetup: WARNING: decrypt_derived device 
$derived not found in crypttab" >&2
                fi
        fi
}

# node_is_in_crypttab() - test whether a device is configured in /etc/crypttab
#
# expected arguments:
# * crypttab target device names (without /dev/mapper/ prefix)
#
# This function takes a target device name and fails if it is not
# configured in /etc/crypttab.
#
node_is_in_crypttab() {
        [ -f /etc/crypttab ] || return 1
        sed -n '/^[^#]/ s/\s.*//p' /etc/crypttab | grep -Fxq "$1"
}

# node_or_pv_is_in_crypttab() - test whether devices are configured in 
/etc/crypttab
#
# expected arguments:
# * crypttab target device names (without /dev/mapper/ prefix), or LVM
#   logical volume device-mapper name (format <VG>-<LV>)
#
# This function fails unless every argument is either a target device
# name configured in /etc/crypttab, or an LVM logical volume
# device-mapper name (format <VG>-<LV>) with only parents devices (PVs)
# configured in /etc/crypttab.
#
node_or_pv_is_in_crypttab() {
        local node lvmnodes lvmnode
        for node in "$@"; do
                if ! node_is_in_crypttab "$node"; then
                        lvmnodes="$(get_lvm_deps "$node" --assert-crypt)" || 
return 1
                        [ "$lvmnodes" ] || return 1
                        for lvmnode in $lvmnodes; do
                                node_is_in_crypttab "$lvmnode" || return 1
                        done
                fi
        done
        return 0
}

# get_lvm_deps() - determine the parent devices (PVs) of a LVM logical volume
#
# expected arguments:
# * LVM logical volume device-mapper name (format <VG>-<LV>)
# * optional options to the function
#
# This function takes a LVM logical volume name and determines the corresponding
# crypted physical volumes (PVs). It returns the name of the underlying
# device-mapper crypt devices (without /dev/mapper).
# If option '--assert-crypt' is given as second argument, then the
# function fails unless all PVs are dm-crypt devices.
#
get_lvm_deps() {
        local node opt deps maj min depnode
        node="$1"
        opt="${2:-}"

        if [ -z "$node" ]; then
                echo "cryptsetup: WARNING: get_lvm_deps - invalid arguments" >&2
                return 1
        fi

        if ! deps=$(vgs --noheadings -o pv_name $(dmsetup --noheadings 
splitname $node | cut -d':' -f1) 2>/dev/null); then
                # $node is not a LVM node, stopping here
                [ "$opt" != '--assert-crypt' ] && return 0 || return 1
        fi

        # We should now have a list of physical volumes for the VG
        for dep in $deps; do
                depnode=$(dmsetup info -c --noheadings -o name "$dep" 
2>/dev/null)
                if [ -z "$depnode" ]; then
                        [ "$opt" != '--assert-crypt' ] && continue || return 1
                fi
                if [ "$(dmsetup table "$depnode" 2>/dev/null | cut -d' ' -f3)" 
!= "crypt" ]; then
                        get_lvm_deps "$depnode" $opt || return 1
                        continue
                fi
                printf '%s\n' "$depnode"
        done

        return 0
}

# get_device_opts() - determine and set options for a crypttab target device
#
# expected arguments:
# * crypttab target device name (without /dev/mapper/ prefix)
# * optional extra options
#
# This function determines options for a crypttab target device and sets them
# accordingly. In order to detect the options, it parses the corresponding
# /etc/crypttab entry and takes optional extra options as second argument.
# Some sanity checks are done on the corresponding source device and configured
# options.
# After everything is processed, the options are saved in '$OPTIONS' for later
# access by parent functions.
#
get_device_opts() {
        local target source link extraopts rootopts opt key
        target="$1"
        extraopts="$2"
        KEYSCRIPT=""
        KEYFILE="" # key file to copy to the initramfs image
        CRYPTHEADER=""
        OPTIONS=""

        if [ -z "$target" ]; then
                echo "cryptsetup: WARNING: get_device_opts - invalid arguments" 
>&2
                return 1
        fi

        opt="$( awk -vtarget="$target" '$1 == target {gsub(/[ \t]+/," "); 
print; exit}' /etc/crypttab )"
        source=$( printf '%s' "$opt" | cut -d " " -f2 )
        key=$( printf '%s' "$opt" | cut -d " " -f3 )
        rootopts=$( printf '%s' "$opt" | cut -d " " -f4- )

        if [ -z "$opt" ] || [ -z "$source" ] || [ -z "$key" ] || [ -z 
"$rootopts" ]; then
                echo "cryptsetup: WARNING: invalid line in /etc/crypttab for 
$target - $opt" >&2
                return 1
        fi

        # Sanity checks for $source
        if [ -h "$source" ]; then
                link=$(readlink -nqe "$source")
                if [ -z "$link" ]; then
                        echo "cryptsetup: WARNING: $source is a dangling 
symlink" >&2
                        return 1
                fi

                if [ "$link" != "${link#/dev/mapper/}" ]; then
                        echo "cryptsetup: NOTE: using $link instead of $source 
for $target" >&2
                        source="$link"
                fi
        fi

        if [ "UUID=${source#UUID=}" = "$source" -a ! \( -b 
"/dev/disk/by-uuid/${source#UUID=}" -o -b 
"/dev/disk/by-partuuid/${source#UUID=}" \) ] || [ "UUID=${source#UUID=}" != 
"$source" -a ! -b "$source" ]; then
                echo "cryptsetup: WARNING: Invalid source device $source" >&2
        fi

        # Sanity checks for $key
        if [ "$key" = "/dev/random" ] || [ "$key" = "/dev/urandom" ]; then
                echo "cryptsetup: WARNING: target $target has a random key, 
skipped" >&2
                return 1
        fi

        if [ -n "$extraopts" ]; then
                rootopts="$extraopts,$rootopts"
        fi

        # We have all the basic options, let's go trough them
        OPTIONS="target=$target,source=$source"
        local IFS_BCK="$IFS"
        local IFS=", "
        unset HASH_FOUND
        unset LUKS_FOUND
        for opt in $rootopts; do
                case $opt in
                        cipher=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        size=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        hash=*)
                                OPTIONS="$OPTIONS,$opt"
                                HASH_FOUND=1
                                ;;
                        tries=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        discard)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        luks)
                                LUKS_FOUND=1
                                ;;
                        header=*)
                                opt="${opt#header=}"
                                if [ ! -e "$opt" ]; then
                                        echo "cryptsetup: WARNING: target 
$target has an invalid header, skipped" >&2
                                        return 1
                                fi
                                CRYPTHEADER="$opt"
                                OPTIONS="$OPTIONS,header=$CRYPTHEADER"
                                ;;
                        tcrypt)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        keyscript=*)
                                opt="${opt#keyscript=}"
                                if [ ! -x "/lib/cryptsetup/scripts/$opt" ] && [ 
! -x "$opt" ]; then
                                        echo "cryptsetup: WARNING: target 
$target has an invalid keyscript, skipped" >&2
                                        return 1
                                fi
                                KEYSCRIPT="$opt"
                                
OPTIONS="$OPTIONS,keyscript=/lib/cryptsetup/scripts/$(basename "$opt")"
                                ;;
                        keyslot=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        veracrypt)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        lvm=*)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        rootdev)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        resumedev)
                                OPTIONS="$OPTIONS,$opt"
                                ;;
                        *)
                                # Presumably a non-supported option
                                ;;
                esac
        done
        IFS="$IFS_BCK"

        # Warn for missing hash option, unless we have a LUKS partition
        if [ -z "$HASH_FOUND" ] && [ -z "$LUKS_FOUND" ]; then
                echo "WARNING: Option hash missing in crypttab for target 
$target, assuming ripemd160." >&2
                echo "         If this is wrong, this initramfs image will not 
boot." >&2
                echo "         Please read 
/usr/share/doc/cryptsetup/README.initramfs.gz and add" >&2
                echo "         the correct hash option to your /etc/crypttab."  
>&2
        fi

        # Warn that header only applies to a LUKS partition currently
        if [ -n "$CRYPTHEADER" ] && [ -z "$LUKS_FOUND" ]; then
                echo "WARNING: Option LUKS missing in crypttab for target 
$target." >&2
                echo "         Headers are only supported for LUKS devices." >&2
        fi

        # If keyscript is set, the "key" is just an argument to the script
        if [ "$key" != "none" ] && [ -z "$KEYSCRIPT" ]; then
                case "$key" in
                        $KEYFILE_PATTERN)
                                KEYFILE="$key"
                                key="/cryptroot-keyfiles/${target}.key"
                                ;;
                        *)
                                key=$(readlink -e "$key")
                                # test whether $target is a root device (or 
parent of the root device)
                                if printf '%s' "$OPTIONS" | grep -Eq 
'^(.*,)?rootdev(,.*)?$'; then
                                        echo "cryptsetup: WARNING: root target 
$target uses a key file, skipped" >&2
                                        return 1
                                # test whether a) key file is not on root fs
                                #           or b) root fs is not encrypted
                                elif [ "$(stat -c %m -- "$key" 2>/dev/null)" != 
/ ] || ! node_or_pv_is_in_crypttab $rootdevs; then
                                        echo "cryptsetup: WARNING: $target's 
key file $key is not on an encrypted root FS, skipped" >&2
                                        return 1
                                fi
                                if printf '%s' "$OPTIONS" | grep -Eq 
'^(.*,)?resumedev(,.*)?$'; then
                                        # we'll be able to decrypt the device, 
but won't be able to use it for resuming
                                        echo "cryptsetup: WARNING: resume 
device $source uses a key file" >&2
                                fi
                                # prepend "/root" (to be substituted by the 
real root FS
                                # mountpoint "$rootmnt" in the boot script) to 
the
                                # absolute filename
                                key="/root$key"
                                ;;
                esac
                OPTIONS="$OPTIONS,keyscript=cat"
        fi
        OPTIONS="$OPTIONS,key=$key"
}

# get_device_modules() - determine required crypto kernel modules for device
#
# expected arguments:
# * crypttab target device name (without /dev/mapper/ prefix)
#
# This function determines the required crypto kernel modules for cipher,
# block cipher and optionally ivhash of the target device and returns them.
#
get_device_modules() {
        local node value cipher blockcipher ivhash
        node="$1"

        # Check the ciphers used by the active root mapping
        value=$(dmsetup table "$node" | cut -d " " -f4)
        cipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f1)
        blockcipher=$(echo "$value" | cut -d ":" -f1 | cut -d "-" -f2)
        ivhash=$(echo "$value" | cut -d ":" -s -f2)

        if [ -n "$cipher" ]; then
                echo "$cipher"
        else
                return 1
        fi

        if [ -n "$blockcipher" ] && [ "$blockcipher" != "plain" ]; then
                echo "$blockcipher"
        fi

        if [ -n "$ivhash" ] && [ "$ivhash" != "plain" ]; then
                echo "$ivhash"
        fi
        return 0
}

# canonical_device() - determine the 
#
# expected arguments:
# * device (either full path or LABEL=<x> or UUID=<y>)
# * optional options to the function
#
# This function takes a device as argument and determines the corresponding
# canonical device name.
# If option '--no-simplify' is given as second argument, then the origin device
# path after unraveling LABEL= and UUID= format and following symlinks is
# returned.
# If no option is given, the device is further unraveled and depending on the
# device path, either the corresponding device-mapper path (as found in
# /dev/mapper/) or the the corresponding disk symlink (as found in
# /dev/disk/by-*/) is returned.
#
canonical_device() {
        local dev altdev original
        dev="$1"
        opt="$2"

        if [ "${dev#LABEL=}" != "$dev" ]; then
                altdev="${dev#LABEL=}"
                dev="/dev/disk/by-label/$(printf '%s' "$altdev" | sed 
's,/,\\x2f,g')"
        elif [ "${dev#UUID=}" != "$dev" ]; then
                altdev="${dev#UUID=}"
                dev="/dev/disk/by-uuid/$altdev"
        fi

        original="$dev"
        if [ -h "$dev" ]; then
                dev=$(readlink -e "$dev")
        fi

        if [ "$opt" = "--no-simplify" ]; then
                printf '%s' "$dev"
                return 0
        fi

        if [ "x${dev%/dev/dm-*}" = "x" ]; then
                # try to detect corresponding symlink in /dev/mapper/
                for dmdev in /dev/mapper/*; do
                        if [ "$(readlink -e "$dmdev")" = "$dev" ]; then
                                dev="$dmdev"
                        fi
                done
        fi

        altdev="${dev#/dev/mapper/}"
        if [ "$altdev" != "$dev" ]; then
                printf '%s' "$altdev"
                return 0
        elif [ "x${original%/dev/disk/by-*/*}" = "x" ]; then
                # support crypttab UUID/LABEL entries
                # this is a /dev/disk/by-*/ path so return just the 'basename'
                echo "${original##/dev/disk/by-*/}"
                return 0
        fi

        echo "cryptsetup: WARNING: failed to detect canonical device of 
$original" >&2
        return 1
}

# add_device() - Process a given device and add to /conf/conf.d/cryptroot
#
# expected arguments:
# * device name (either crypttab target device name without /dev/mapper/ prefix
#                    or LVM device-mapper name in format '<VG>:<LV>')
#
# This function takes a device name, does all required processing and adds the
# result with all device options to /conf/conf.d/cryptroot in the initramfs.
# Additionally, it returns required kernel modules.
#
add_device() {
        local node nodes lvmnodes opts lastopts i count
        nodes="$1"
        opts=""     # Applied to all nodes
        lastopts="" # Applied to last node

        if [ -z "$nodes" ]; then
                return 0
        fi

        # Flag root and resume devices
        if printf '%s' "$rootdevs" | tr ' ' '\n' | grep -Fxq "$nodes"; then
                opts="${opts:+$opts,}rootdev"
        fi
        if printf '%s' "$resumedevs" | tr ' ' '\n' | grep -Fxq "$nodes"; then
                opts="${opts:+$opts,}resumedev"
        fi

        # Check that it is a node under /dev/mapper/
        # nodes=$(canonical_device "$nodes") || return 0

        # Can we find this node in crypttab
        if ! node_is_in_crypttab "$nodes"; then
                # dm node but not in crypttab, is it a lvm device backed by 
dm-crypt nodes?
                lvmnodes=$(get_lvm_deps "$nodes") || return 1

                # not backed by any dm-crypt nodes; stop here
                if [ -z "$lvmnodes" ]; then
                    return 0
                fi

                # It is a lvm device!
                opts="${opts:+$opts,}lvm=$nodes"
                nodes="$lvmnodes"
        fi

        # Prepare to setup each node
        count=$(printf '%s' "$nodes" | wc -w)
        i=1
        for node in $nodes; do
                # Prepare the additional options
                if [ $i -eq $count ]; then
                        if [ -n "$lastopts" ]; then
                                opts="${opts:+$opts,}$lastopts"
                        fi
                fi

                # Get crypttab root options
                if ! get_device_opts "$node" "$opts"; then
                        continue
                fi
                printf '%s\n' "$OPTIONS" >>"$DESTDIR/conf/conf.d/cryptroot"

                # If we have a keyscript, make sure it is included
                if [ -n "$KEYSCRIPT" ]; then
                        if [ ! -d "$DESTDIR/lib/cryptsetup/scripts" ]; then
                                mkdir -p "$DESTDIR/lib/cryptsetup/scripts"
                        fi

                        if [ -e "/lib/cryptsetup/scripts/$KEYSCRIPT" ]; then
                                copy_exec "/lib/cryptsetup/scripts/$KEYSCRIPT" 
/lib/cryptsetup/scripts >&2
                        elif [ -e "$KEYSCRIPT" ]; then
                                copy_exec "$KEYSCRIPT" /lib/cryptsetup/scripts 
>&2
                        elif KSTYPE="$(type "$KEYSCRIPT" 2>&1)"; then
                                if [ -x "${KSTYPE#"$KEYSCRIPT" is }" ]; then
                                        copy_exec "${KSTYPE#"$KEYSCRIPT" is }" 
/lib/cryptsetup/scripts >&2
                                fi
                        else
                                echo "cryptsetup: WARNING: failed to find 
keyscript $KEYSCRIPT" >&2
                                continue
                        fi
                elif [ -n "$KEYFILE" ]; then
                        case "$KEYFILE" in
                                $KEYFILE_PATTERN)
                                        mkdir -pm0700 
"$DESTDIR/cryptroot-keyfiles"
                                        cp --preserve=all "$KEYFILE" 
"$DESTDIR/cryptroot-keyfiles/${node}.key"
                                        ;;
                        esac
                fi

                # If we have a LUKS header, make sure it is included
                # TODO: make it configurable to include the LUKS header into 
initramfs
                # disabled for now due to security reasons
                if [ -n "$CRYPTHEADER" ]; then
                        if [ ! -d "$DESTDIR/conf/conf.d/cryptheader" ]; then
                                mkdir -p "$DESTDIR/conf/conf.d/cryptheader"
                        fi

                        #if [ -e "$CONFDIR/conf.d/cryptheader/$CRYPTHEADER" ]; 
then
                        #       copy_exec 
"$CONFDIR/conf.d/cryptheader/$CRYPTHEADER" /conf/conf.d/cryptheader >&2
                        #elif [ -e "$CRYPTHEADER" ]; then
                        #       copy_exec "$CRYPTHEADER" 
/conf/conf.d/cryptheader >&2
                        #else
                        #       echo "cryptsetup: WARNING: failed to find LUKS 
header $CRYPTHEADER" >&2
                        #       continue
                        #fi
                fi
                

                # Calculate needed modules
                modules=$(get_device_modules $node | sort | uniq)
                if [ -z "$modules" ]; then
                        echo "cryptsetup: WARNING: failed to determine cipher 
modules to load for $node" >&2
                        continue
                fi
                echo dm_mod
                echo dm_crypt
                echo "$modules"
                # Load hardware aes module
                if cpu_has_aesni; then
                        echo aesni
                fi
                i=$(( $i + 1 ))
        done

        return 0
}

# cpu_has_aesni() - Detect whether the host CPU has AES-NI support
#
# expected arguments:
# * none
#
# This functions returns true when the host CPU has AES-NI support.
#
cpu_has_aesni() {
        return $(grep -q "^flags\s*:\s*.*aes" /proc/cpuinfo)
}

# add_crypto_modules() - determine kernel module path and add to initramfs
#
# expected arguments:
# * kernel module name
#
# This function takes a kernel module name, determines the corresponding path
# and runs manual_add_modules() from initramfs hook functions to add the module
# to the initramfs.
#
add_crypto_modules() {
        local mod file altmod found genericfound
        mod="$1"
        found=""
        genericfound=""

        if [ -z "$mod" ]; then
                return 1
        fi

        # We have several potential sources of modules (in order of preference):
        #
        #   a) /lib/modules/$VERSION/kernel/arch/$ARCH/crypto/$mod-$specific.ko
        #   b) /lib/modules/$VERSION/kernel/crypto/$mod_generic.ko
        #   c) /lib/modules/$VERSION/kernel/crypto/$mod.ko
        #
        # and (currently ignored):
        #
        #   d) /lib/modules/$VERSION/kernel/drivers/crypto/$specific-$mod.ko

        for file in $(find "$MODULESDIR/kernel/arch/" -name "$mod-*.ko" 
2>/dev/null); do
                altmod="${file##*/}"
                altmod="${altmod%.ko}"
                manual_add_modules "$altmod"
                found="yes"
        done

        for file in $(find "$MODULESDIR/kernel/crypto/" -name 
"${mod}_generic.ko" 2>/dev/null); do
                altmod="${file##*/}"
                altmod="${altmod%.ko}"
                manual_add_modules "$altmod"
                found="yes"
                genericfound="yes"
        done

        if [ -z "$genericfound" ]; then
                for file in $(find "$MODULESDIR/kernel/crypto/" -name 
"${mod}.ko" 2>/dev/null); do
                        altmod="${file##*/}"
                        altmod="${altmod%.ko}"
                        manual_add_modules "$altmod"
                        found="yes"
                done
        fi

        if [ -z "$found" ]; then
                return 1
        fi

        return 0
}

#
# Begin real processing
#

setup="no"
rootdevs=""
usrdevs=""
resumedevs=""

# XXX Backward compatibility: remove once Stretch has been promoted stable
for v in CRYPTSETUP KEYFILE_PATTERN; do
        if eval [ "\${$v+x}" ]; then
                echo "WARNING: Setting $v in 
/etc/initramfs-tools/initramfs.conf" \
                     "is deprecated and will stop working in the future." \
                     "Use /etc/cryptsetup-initramfs/conf-hook instead." >&2
        fi
done

# Load the hook's config
if [ -f "/etc/cryptsetup-initramfs/conf-hook" ]; then
        . /etc/cryptsetup-initramfs/conf-hook
fi

# Include cryptsetup modules, regardless of _this_ machine configuration
if [ -n "$CRYPTSETUP" ] && [ "$CRYPTSETUP" != "n" ]; then
        setup="yes"
fi

if [ "$KEYFILE_PATTERN" ]; then
        setup="yes"
        case "${UMASK:-$(umask)}" in
                0[0-7]77) ;;
                *) echo "WARNING: permissive UMASK (${UMASK:-$(umask)})." \
                        "Private key material inside the initrd might be left 
unprotected." >&2
                ;;
        esac
fi

# Find the root and resume device(s)
if [ -r /etc/crypttab ]; then
        rootdevs=$(get_fs_devices /)
        if [ -z "$rootdevs" ]; then
                echo "cryptsetup: WARNING: could not determine root device from 
/etc/fstab" >&2
        fi
        usrdevs=$(get_fs_devices /usr)
        resumedevs=$(get_resume_devices)
        initramfsdevs=$(get_initramfs_devices)
fi

# Load the config opts and modules for each device
for dev in $rootdevs $usrdevs $resumedevs $initramfsdevs; do
        if ! modules=$(add_device "$dev"); then
                echo "cryptsetup: FAILURE: could not determine configuration 
for $dev" >&2
                continue
        fi

        if [ -n "$modules" ]; then
                setup="yes"
        fi

        if [ "$setup" = "no" ]; then
                continue
        fi

        if [ "$MODULES" = "most" ]; then
                archcrypto="$(find "$MODULESDIR/kernel/arch" -type d -name 
"crypto" 2>/dev/null)"
                if [ -n "$archcrypto" ]; then
                        copy_modules_dir "${archcrypto##*${MODULESDIR}/}"
                fi
                copy_modules_dir "kernel/crypto"
        else
                for mod in $modules; do
                        add_crypto_modules $mod
                done
        fi
done

# With large initramfs, we always add a basic subset of modules
if [ "$MODULES" != "dep" ] && [ "$setup" = "yes" ]; then
        for mod in aes cbc chainiv cryptomgr krng sha256 xts; do
                add_crypto_modules $mod
        done
fi

# See if we need to add the basic components
if [ "$setup" = "yes" ]; then
        for mod in dm_mod dm_crypt; do
                manual_add_modules $mod
        done

        copy_exec /sbin/cryptsetup
        copy_exec /sbin/dmsetup
        copy_exec /lib/cryptsetup/askpass

        # We need sed. Either via busybox or as standalone binary.
        if [ "$BUSYBOX" = "n" ] || [ ! -e ${BUSYBOXDIR}/busybox ]; then
                copy_exec /bin/sed
        fi
fi

exit 0
#!/bin/sh

PREREQ="cryptroot-prepare"

#
# Standard initramfs preamble
#
prereqs()
{
        # Make sure that cryptroot is run last in local-top
        for req in $(dirname $0)/*; do
                script=${req##*/}
                if [ $script != cryptroot ]; then
                        echo $script
                fi
        done
}

case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac

# source for log_*_msg() functions, see LP: #272301
. /scripts/functions

#
# Helper functions
#
message()
{
        if [ -x /bin/plymouth ] && plymouth --ping; then
                plymouth message --text="$@"
        elif [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write 
]; then
                usplash_write "TEXT-URGENT $@"
        else
                echo "$@" >&2
        fi
        return 0
}

udev_settle()
{
        # Wait for udev to be ready, see https://launchpad.net/bugs/85640
        if command -v udevadm >/dev/null 2>&1; then
                udevadm settle --timeout=30
        elif command -v udevsettle >/dev/null 2>&1; then
                udevsettle --timeout=30
        fi
        return 0
}

parse_options()
{
        local cryptopts
        cryptopts="$1"

        if [ -z "$cryptopts" ]; then
                return 1
        fi

        # Defaults
        cryptcipher=aes-cbc-essiv:sha256
        cryptsize=256
        crypthash=ripemd160
        crypttarget=cryptroot
        cryptsource=""
        cryptheader=""
        cryptlvm=""
        cryptkeyscript=""
        cryptkey="" # This is only used as an argument to an eventual keyscript
        cryptkeyslot=""
        crypttries=3
        crypttcrypt=""
        cryptveracrypt=""
        cryptrootdev=""
        cryptdiscard=""
        CRYPTTAB_OPTIONS=""

        local IFS=" ,"
        for x in $cryptopts; do
                case $x in
                hash=*)
                        crypthash=${x#hash=}
                        ;;
                size=*)
                        cryptsize=${x#size=}
                        ;;
                cipher=*)
                        cryptcipher=${x#cipher=}
                        ;;
                target=*)
                        crypttarget=${x#target=}
                        export CRYPTTAB_NAME="$crypttarget"
                        ;;
                source=*)
                        cryptsource=${x#source=}
                        if [ ${cryptsource#UUID=} != $cryptsource ]; then
                                
cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}"
                        elif [ ${cryptsource#LABEL=} != $cryptsource ]; then
                                cryptsource="/dev/disk/by-label/$(printf '%s' 
"${cryptsource#LABEL=}" | sed 's,/,\\x2f,g')"
                        elif [ ${cryptsource#ID=} != $cryptsource ]; then
                                cryptsource="/dev/disk/by-id/${cryptsource#ID=}"
                        fi
                        export CRYPTTAB_SOURCE="$cryptsource"
                        ;;
                header=*)
                        cryptheader=${x#header=}
                        if [ ! -e "$cryptheader" ] && [ -e 
"/conf/conf.d/cryptheader/$cryptheader" ]; then
                                
cryptheader="/conf/conf.d/cryptheader/$cryptheader"
                        fi
                        export CRYPTTAB_HEADER="$cryptheader"
                        ;;
                lvm=*)
                        cryptlvm=${x#lvm=}
                        ;;
                keyscript=*)
                        cryptkeyscript=${x#keyscript=}
                        ;;
                key=*)
                        if [ "${x#key=}" != "none" ]; then
                                cryptkey=${x#key=}
                        fi
                        export CRYPTTAB_KEY="$cryptkey"
                        ;;
                keyslot=*)
                        cryptkeyslot=${x#keyslot=}
                        ;;
                tries=*)
                        crypttries="${x#tries=}"
                        case "$crypttries" in
                          *[![:digit:].]*)
                                crypttries=3
                                ;;
                        esac
                        ;;
                tcrypt)
                        crypttcrypt="yes"
                        ;;
                veracrypt)
                        cryptveracrypt="--veracrypt"
                        ;;
                rootdev)
                        cryptrootdev="yes"
                        ;;
                discard)
                        cryptdiscard="yes"
                        ;;
                esac
                PARAM="${x%=*}"
                if [ "$PARAM" = "$x" ]; then
                        VALUE="yes"
                else
                        VALUE="${x#*=}"
                fi
                CRYPTTAB_OPTIONS="$CRYPTTAB_OPTIONS $PARAM"
                eval export CRYPTTAB_OPTION_$PARAM="\"$VALUE\""
        done
        export CRYPTTAB_OPTIONS

        if [ -z "$cryptsource" ]; then
                message "cryptsetup ($crypttarget): source parameter missing"
                return 1
        fi
        return 0
}

activate_vg()
{
        # Sanity checks
        if [ ! -x /sbin/lvm ]; then
                message "cryptsetup ($crypttarget): lvm is not available"
                return 1
        fi

        # Detect and activate available volume groups
        /sbin/lvm vgscan
        /sbin/lvm vgchange -a y --sysinit
        return $?
}

setup_mapping()
{
        local opts count cryptopen cryptremove NEWROOT is_luks
        opts="$1"
        is_luks=0

        if [ -z "$opts" ]; then
                return 0
        fi

        parse_options "$opts" || return 1

        if [ -z "$cryptkeyscript" ]; then
                if [ ${cryptsource#/dev/disk/by-uuid/} != $cryptsource ]; then
                        # UUIDs are not very helpful
                        diskname="$crypttarget"
                else
                        diskname="$cryptsource ($crypttarget)"
                fi
                cryptkeyscript="/lib/cryptsetup/askpass"
                cryptkey="1Please unlock disk $diskname: "
        elif ! type "$cryptkeyscript" >/dev/null; then
                message "cryptsetup ($crypttarget): error - script 
\"$cryptkeyscript\" missing"
                return 1
        fi

        if [ "$cryptkeyscript" = "cat" ] && [ "${cryptkey#/root/}" != 
"$cryptkey" ]; then
                # skip the mapping if the root FS is not mounted yet
                sed -rn 's/^\s*[^#]\S*\s+(\S+)\s.*/\1/p' /proc/mounts | grep 
-Fxq "$rootmnt" || return 1
                # substitute the "/root" prefix by the real root FS mountpoint 
otherwise
                cryptkey="${rootmnt}/${cryptkey#/root/}"
        fi

        if [ -n "$cryptheader" ] && ! type "$cryptheader" >/dev/null; then
                message "cryptsetup ($crypttarget): error - LUKS header 
\"$cryptheader\" missing"
                return 1
        fi

        # The same target can be specified multiple times
        # e.g. root and resume lvs-on-lvm-on-crypto
        if [ -e "/dev/mapper/$crypttarget" ]; then
                return 0
        fi

        modprobe -q dm_crypt

        # Make sure the cryptsource device is available
        if [ ! -e $cryptsource ]; then
                activate_vg
        fi

        # If the encrypted source device hasn't shown up yet, give it a
        # little while to deal with removable devices

        # the following lines below have been taken from
        # /usr/share/initramfs-tools/scripts/local, as suggested per
        # https://launchpad.net/bugs/164044
        if [ ! -e "$cryptsource" ]; then
                log_begin_msg "Waiting for encrypted source device..."

                # Default delay is 180s
                if [ -z "${ROOTDELAY}" ]; then
                        slumber=180
                else
                        slumber=${ROOTDELAY}
                fi
                if [ -x /sbin/usplash_write ]; then
                        /sbin/usplash_write "TIMEOUT ${slumber}" || true
                fi

                slumber=$(( ${slumber} * 10 ))
                while [ ! -e "$cryptsource" ]; do
                        # retry for LVM devices every 10 seconds
                        if [ ${slumber} -eq $(( ${slumber}/100*100 )) ]; then
                                activate_vg
                        fi

                        /bin/sleep 0.1
                        slumber=$(( ${slumber} - 1 ))
                        [ ${slumber} -gt 0 ] || break
                done

                if [ ${slumber} -gt 0 ]; then
                        log_end_msg 0
                else
                        log_end_msg 1 || true
                fi
                if [ -x /sbin/usplash_write ]; then
                        /sbin/usplash_write "TIMEOUT 15" || true
                fi
        fi
        udev_settle

        # We've given up, but we'll let the user fix matters if they can
        if [ ! -e "${cryptsource}" ]; then
                
                echo "  ALERT! ${cryptsource} does not exist."
                echo "  Check cryptopts=source= bootarg: cat /proc/cmdline"
                echo "  or missing modules, devices: cat /proc/modules; ls /dev"
                panic -r "Dropping to a shell. Will skip ${cryptsource} if you 
can't fix."
        fi

        if [ ! -e "${cryptsource}" ]; then
                return 1
        fi


        # Prepare commands
        cryptopen="/sbin/cryptsetup -T 1"
        if [ "$cryptdiscard" = "yes" ]; then
                cryptopen="$cryptopen --allow-discards"
        fi
        if [ -n "$cryptheader" ]; then
                cryptopen="$cryptopen --header=$cryptheader"
        fi
        if [ -n "$cryptkeyslot" ]; then
                cryptopen="$cryptopen --key-slot=$cryptkeyslot"
        fi
        if /sbin/cryptsetup isLuks ${cryptheader:-$cryptsource} >/dev/null 
2>&1; then
                is_luks=1
                cryptopen="$cryptopen open --type luks $cryptsource 
$crypttarget --key-file=-"
        elif [ "$crypttcrypt" = "yes" ]; then
                cryptopen="$cryptopen open --type tcrypt $cryptveracrypt 
$cryptsource $crypttarget"
        else
                cryptopen="$cryptopen -c $cryptcipher -s $cryptsize -h 
$crypthash open --type plain $cryptsource $crypttarget --key-file=-"
        fi
        cryptremove="/sbin/cryptsetup remove $crypttarget"
        NEWROOT="/dev/mapper/$crypttarget"

        # Try to get a satisfactory password $crypttries times
        count=0
        while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do
                export CRYPTTAB_TRIED="$count"
                if [ $count -gt 1 ]; then
                        /bin/sleep 3
                fi

                if [ -z "$cryptkeyscript" -a "$is_luks" -eq "1" ]; then
                        cryptkey="Unlocking the disk $cryptsource 
($crypttarget)\nEnter passphrase: "
                        if [ -x /bin/plymouth ] && plymouth --ping; then
                                cryptkeyscript="plymouth ask-for-password 
--prompt"
                                cryptkey=$(echo -e "$cryptkey")
                        else
                                cryptkeyscript="/lib/cryptsetup/askpass"
                        fi
                fi

                if [ -n "$CACHED_PASSWORD" ]; then
                        if ! crypttarget="$crypttarget" 
cryptsource="$cryptsource" \
                             echo -n "$CACHED_PASSWORD" | $cryptopen 
2>/dev/null; then
                                unset CACHED_PASSWORD
                        fi
                fi

                count=$(( $count + 1 ))

                if [ -z "$CACHED_PASSWORD" ]; then
                        CACHED_PASSWORD="`$cryptkeyscript \"$cryptkey\"`"
                        if ! crypttarget="$crypttarget" 
cryptsource="$cryptsource" \
                             echo -n "$CACHED_PASSWORD" | $cryptopen; then
                                message "cryptsetup: cryptsetup failed, bad 
password or options?"
                                unset CACHED_PASSWORD
                                continue
                        fi
                fi

                if [ ! -e "$NEWROOT" ]; then
                        message "cryptsetup ($crypttarget): unknown error 
setting up device mapping"
                        return 1
                fi

                #FSTYPE=''
                #eval $(fstype < "$NEWROOT")
                FSTYPE="$(/sbin/blkid -s TYPE -o value "$NEWROOT")"

                # See if we need to setup lvm on the crypto device
                #if [ "$FSTYPE" = "lvm" ] || [ "$FSTYPE" = "lvm2" ]; then
                if [ "$FSTYPE" = "LVM_member" ] || [ "$FSTYPE" = "LVM2_member" 
]; then
                        if [ -z "$cryptlvm" ]; then
                                message "cryptsetup ($crypttarget): lvm fs 
found but no lvm configured"
                                return 1
                        elif ! activate_vg; then
                                # disable error message, LP: #151532
                                #message "cryptsetup ($crypttarget): failed to 
setup lvm device"
                                return 1
                        fi

                        # Apparently ROOT is already set in /conf/param.conf for
                        # flashed kernels at least. See bugreport #759720.
                        if [ -f /conf/param.conf ] && grep -q "^ROOT=" 
/conf/param.conf; then
                                NEWROOT=$(sed -n 's/^ROOT=//p' /conf/param.conf)
                        else
                                NEWROOT=${cmdline_root:-/dev/mapper/$cryptlvm}
                                if [ "$cryptrootdev" = "yes" ]; then
                                        # required for lilo to find the root 
device
                                        echo "ROOT=$NEWROOT" >>/conf/param.conf
                                fi
                        fi
                        #eval $(fstype < "$NEWROOT")
                        FSTYPE="$(/sbin/blkid -s TYPE -o value "$NEWROOT")"
                fi

                #if [ -z "$FSTYPE" ] || [ "$FSTYPE" = "unknown" ]; then
                if [ -z "$FSTYPE" ]; then
                        message "cryptsetup ($crypttarget): unknown fstype, bad 
password or options?"
                        udev_settle
                        $cryptremove
                        unset CACHED_PASSWORD
                        continue
                fi

                # decrease $count by 1, apparently last try was successful.
                count=$(( $count - 1 ))

                message "cryptsetup ($crypttarget): set up successfully"
                
                export CACHED_PASSWORD
                
                break
        done

        failsleep=60 # make configurable later?

        if [ "$cryptrootdev" = "yes" ] && [ $crypttries -gt 0 ] && [ $count -ge 
$crypttries ]; then
                message "cryptsetup ($crypttarget): maximum number of tries 
exceeded"
                message "cryptsetup: going to sleep for $failsleep seconds..."
                sleep $failsleep
                exit 1
        fi

        udev_settle
        return 0
}

exit_script()
{
        CACHED_PASSWORD="`dd bs=512 if=/dev/random count=1 2>/dev/null `"
        unset CACHED_PASSWORD
        exit $1
}

#
# Begin real processing
#

# Do we have any kernel boot arguments?
cmdline_cryptopts=''
unset cmdline_root
for opt in $(cat /proc/cmdline); do
        case $opt in
        cryptopts=*)
                opt="${opt#cryptopts=}"
                if [ -n "$opt" ]; then
                        if [ -n "$cmdline_cryptopts" ]; then
                                cmdline_cryptopts="$cmdline_cryptopts $opt"
                        else
                                cmdline_cryptopts="$opt"
                        fi
                fi
                ;;
        root=*)
                opt="${opt#root=}"
                case $opt in
                /*) # Absolute path given. Not lilo major/minor number.
                        cmdline_root=$opt
                        ;;
                *) # lilo major/minor number (See #398957). Ignore
                esac
                ;;
        esac
done

if [ -n "$cmdline_cryptopts" ]; then
        # Call setup_mapping separately for each possible cryptopts= setting
        for cryptopt in $cmdline_cryptopts; do
                setup_mapping "$cryptopt"
        done
        exit 0
fi

# Do we have any settings from the /conf/conf.d/cryptroot file?
if [ -r /conf/conf.d/cryptroot ]; then
        while read mapping <&3; do
                setup_mapping "$mapping" 3<&-
        done 3< /conf/conf.d/cryptroot
fi

exit_script 0

Ответить