]> git.pld-linux.org Git - projects/geninitrd.git/blobdiff - mod-luks.sh
Timeout here is not a good idea. rootfs cannot be mounted and kernel oopses due to...
[projects/geninitrd.git] / mod-luks.sh
index f58310ad43c44ffc4aa03de5800ff05b395a16bf..ffe87cb46529bf1e355f05a9044ece94089eb13e 100644 (file)
@@ -1,6 +1,4 @@
 #!/bin/sh
-LUKS_RCSID='$Revision$ $Date::                            $'
-
 # geninitrd mod: cryptsetup luks
 USE_LUKS=${USE_LUKS:-yes}
 
@@ -32,37 +30,25 @@ is_luks() {
                return 1
        fi
 
-       if [ ! -e "$node" ]; then
-               warn "is_luks(): node $node doesn't exist!"
-               return 1
-       fi
-
-       local dev dm_status dm_name=${node#/dev/mapper/}
+       local dev dm_name=${node#/dev/mapper/}
        if [ "$node" = "$dm_name" ]; then
-               debug "is_luks: $node is not device mapper name"
+               verbose "is_luks: $node is not device mapper name"
                return 1
        fi
 
-       dev=$(/sbin/cryptsetup status $dm_name 2>/dev/null | awk '/device:/{print $2}')
+       dev=$(awk -vdm_name="$dm_name" '$1 == dm_name { print $2 }' /etc/crypttab)
        if [ "$dev" ]; then
+               dev=$(find_devname "$dev")
                /sbin/cryptsetup isLuks $dev
                rc=$?
        else
-               # If luks partition was activated using old cryptsetup (at initrd level)
-               # then "device:" report could be missing from cryptsetup status above.
-               # Fallback to dmsetup report in such case.
-               dm_status=$(/sbin/dmsetup status --target crypt $dm_name 2>/dev/null)
-               if [ -n "$dm_status" ]; then
-                       rc=0
-               else
-                       rc=1
-               fi
+               rc=1
        fi
 
        if [ $rc = 0 ]; then
-               debug "is_luks: $node is cryptsetup luks"
+               verbose "is_luks: $node is cryptsetup luks"
        else
-               debug "is_luks: $node is not cryptsetup luks"
+               verbose "is_luks: $node is not cryptsetup luks"
        fi
        return $rc
 }
@@ -81,10 +67,15 @@ find_modules_luks() {
        # TODO: autodetect
        find_module "aes"
        find_module "cbc"
+       find_module "-af-alg"
+       find_module "-algif_hash"
+       find_module "-algif_skcipher"
+       find_module "-loop"
 
        # recurse
-       dev=$(awk '$1 == "'"$LUKSNAME"'" { print $2 }' /etc/crypttab)
-       if [ -n "$dev" ] ; then 
+       dev=$(awk -vLUKSNAME="$LUKSNAME" '$1 == LUKSNAME { print $2 }' /etc/crypttab)
+       if [ -n "$dev" ]; then
+               dev=$(find_devname "$dev")
                find_modules_for_devpath $dev
                have_luks=yes
        else
@@ -102,13 +93,14 @@ initrd_gen_luks() {
 
        inst_d /bin
        inst_exec $cryptsetup /bin/cryptsetup
+       inst_d /var/run/cryptsetup
 
        mount_dev
        mount_sys
        initrd_gen_devices
        # TODO: 'udevadm settle' is called by lukssetup, is udev optional?
 
-       debug "luks: process /etc/crypttab $LUKSNAME"
+       verbose "luks: process /etc/crypttab $LUKSNAME"
        luks_crypttab $LUKSNAME
 }
 
@@ -145,20 +137,39 @@ luks_crypttab() {
                        key=""
                fi
 
+               src=$(find_devname "$src")
                if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then
                        if key_is_random "$key"; then
                                die "$dst: LUKS requires non-random key, skipping"
                        fi
-                       if [ -n "$opt" ]; then
-                               warn "$dst: options are invalid for LUKS partitions, ignoring them"
-                       fi
                        if [ "$key" ]; then
                                keyfile=/etc/.$dst.key
                                inst $key $keyfile
                        fi
 
-                       debug "+ cryptsetup ${keyfile:+-d $keyfile} luksOpen '$src' '$dst'"
+                       crypttab_opt=""
+                       old_IFS="$IFS"
+                       IFS=","
+                       for option in $opt; do
+                               case "$option" in
+                                       discard|allow-discards)
+                                               crypttab_opt="$crypttab_opt --allow-discards"
+                                               ;;
+                                       *)
+                                               warn "$dst: option \'$opt\' is invalid for LUKS partitions, ignored"
+                                               ;;
+                               esac
+                       done
+                       IFS="$old_IFS"
+
+                       verbose "+ cryptsetup ${keyfile:+-d $keyfile} open $crypttab_opt '$src' '$dst'"
                        add_linuxrc <<-EOF
+                       debugshell
+
+                       cryptsetup_opt=""
+                       if [ "\$DEBUGINITRD" ]; then
+                               cryptsetup_opt="--debug"
+                       fi
                        # cryptsetup can be called twice and in case on crypt on lvm only second
                        # will succeed because there will be no src device in first cryptsetup call
                        # this can be called multiple times, before lvm and after lvm.
@@ -166,7 +177,7 @@ luks_crypttab() {
                        if [ \${luksdev##/dev/disk/by-uuid/} != \${luksdev} ]; then
                                src_uuid=\${luksdev##/dev/disk/by-uuid/}
                                while read x y z name; do
-                                       found_uuid=\$(cryptsetup luksUUID /dev/\${name} 2>/dev/null)
+                                       found_uuid=\$(cryptsetup \$cryptsetup_opt luksUUID /dev/\${name} 2>/dev/null)
                                        if [ "\$found_uuid" = "\$src_uuid" ]; then
                                                luksdev=/dev/\$name
                                                break
@@ -175,10 +186,10 @@ luks_crypttab() {
                        fi
 
                        if [ -e "\$luksdev" ]; then
-                               crypt_status=\$(cryptsetup status '$dst')
-                               if [ "\${crypt_status%%is inactive.}" != "\$crypt_status" ]; then
+                               crypt_status=\$(cryptsetup \$cryptsetup_opt status '$dst')
+                               if [ "\${crypt_status%%is inactive*}" != "\$crypt_status" ]; then
                                        # is inactive
-                                       cryptsetup ${keyfile:+-d $keyfile} luksOpen "\$luksdev" '$dst' <&1
+                                       cryptsetup \$cryptsetup_opt ${keyfile:+-d $keyfile} open $crypttab_opt "\$luksdev" '$dst' <&1
                                fi
                        fi
 
This page took 0.793918 seconds and 4 git commands to generate.