Gutsy: cryptsetup fails for encrypted rootfs on slow devices (USB)

Bug #164044 reported by Swâmi Petaramesh on 2007-11-20
Affects Status Importance Assigned to Milestone
cryptsetup (Debian)
Fix Released
cryptsetup (Ubuntu)
Reinhard Tartler
Nominated for Hardy by Andreas Busse
Nominated for Intrepid by Andreas Busse

Bug Description

Binary package hint: cryptsetup

This bug is *not* a duplicate of bug #85460

cryptsetup fails for encrypted rootfs on a device that is slow to come up (i.e. an external USB HD). The "udevsettle" solution proposed in bug #85460 does not help.

I have patched /usr/share/initramfs-tools/scripts/local-top/cryptroot by integrating into it the same kind of "waiting loop" that already exists for a non-encrypted rootfs, in /usr/share/initramfs-tools/scripts/local .

This patch to /usr/share/initramfs-tools/scripts/local-top/cryptroot solves the issue and perfectly does the trick. Please consider integrating this fix.

--- /old/cryptroot 2007-10-11 22:39:56.000000000 +0200
+++ cryptroot 2007-11-20 12:21:25.000000000 +0100
@@ -25,6 +25,9 @@
 # Helper functions
+. /scripts/functions
  local cryptopts
@@ -158,11 +161,45 @@
   /sbin/udevsettle --timeout=30

- if [ ! -e $cryptsource ]; then
- echo "cryptsetup: Source device $cryptsource not found"
- return 1
+ # If the encrypted source device hasn't shown up yet, give it a little while
+ # to deal with removable devices
+ if [ ! -e "$cryptsource" ] || ! /lib/udev/vol_id "$cryptsource" >/dev/null 2>&1; 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" ] || ! /lib/udev/vol_id "$cryptsource" >/dev/null 2>&1; do
+ /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

+ # We've given up, but we'll let the user fix matters if they can
+ while [ ! -e "$cryptsource" ]; do
+ echo " Check cryptopts=source= bootarg cat /proc/cmdline"
+ echo " or missing modules, devices: cat /proc/modules ls /dev"
+ panic "ALERT! $cryptsource does not exist. Dropping to a shell!"
+ done
  # Prepare commands
  if /sbin/cryptsetup isLuks $cryptsource > /dev/null 2>&1; then
   cryptcreate="/sbin/cryptsetup luksOpen $cryptsource $crypttarget"

Gunnar Thielebein (lorem-ipsum) wrote :

could you add information about target version of cryptsetup for which this patch will work?

Reinhard Tartler (siretart) wrote :
Changed in cryptsetup:
assignee: nobody → siretart
importance: Undecided → Low
status: New → In Progress
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package cryptsetup - 2:1.0.6-1ubuntu3

cryptsetup (2:1.0.6-1ubuntu3) intrepid; urgency=low

  * Parse comments in lines not starting with '#', LP: #185380
  * in cryptroot hook, don't rely on 'udevadm settle' to wait long enough
    for the cryptdevice to appear. Reimplement the busy waiting loop found
    while waiting for the root file system. Patch based on work by Swâmi
    Petaramesh. LP: #164044
  * debian/crypdisks.functions: call 'env' with full path. LP: #178829.

 -- Reinhard Tartler <email address hidden> Mon, 26 May 2008 22:12:32 +0200

Changed in cryptsetup:
status: In Progress → Fix Released
Changed in cryptsetup:
status: Unknown → New
unggnu (unggnu) wrote :

This doesn't seem to be fixed in Intrepid. At least I have the problem that initramfs doesn't find the encrypted root-Device on boot with USB hdd while it works fine on my internal.
Can anyone confirm this?

It is fixed. They included a sleep-loop in
/usr/share/initramfs-tools/scripts/local-top/cryptroot. They even
include a reference to this ticket. Here's the code that was added:

        # /usr/share/initramfs-tools/scripts/local, as suggested per
        if [ ! -e "$cryptsource" ] || ! /lib/udev/vol_id
"$cryptsource" >/dev/null 2>&1; then
                log_begin_msg "Waiting for encrypted source device..."

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

                slumber=$(( ${slumber} * 10 ))
                while [ ! -e "$cryptsource" ] || ! /lib/udev/vol_id
"$cryptsource" >/dev/null 2>&1; do
                        /bin/sleep 0.1
                        slumber=$(( ${slumber} - 1 ))
                        [ ${slumber} -gt 0 ] || break

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

On Tue, Dec 2, 2008 at 12:41 PM, unggnu <email address hidden> wrote:
> This doesn't seem to be fixed in Intrepid. At least I have the problem that initramfs doesn't find the encrypted root-Device on boot with USB hdd while it works fine on my internal.
> Can anyone confirm this?
> --
> Gutsy: cryptsetup fails for encrypted rootfs on slow devices (USB)
> You received this bug notification because you are a direct subscriber
> of a duplicate bug.

unggnu (unggnu) wrote :

That's why I haven't reopened this bug report. But what could be wrong if it doesn't find the UUID/device of the encrypted root partition on a USB HDD.
Has anyone tried it with an USB HDD? Boot and root partition have to be on the external device.

gw0 (gw-launchpad) wrote :

I think that this fix is not good in all circumstances. The problem lies in the fact that the "waiting loop" for encrypted devices is NOT the same as for unencrypted devices. In case you are using LUKS everything is OK, because there is a container vol_id can detect, but if you are encrypting with preconfigured paramaters then vol_id has nothing to detect (because it can't decrypt and look what is in there).

I haven't tested it, but I recommend to remove the vol_id check from this two lines:
if [ ! -e "$cryptsource" ] || ! /lib/udev/vol_id "$cryptsource" >/dev/null 2>&1; then
while [ ! -e "$cryptsource" ] || ! /lib/udev/vol_id "$cryptsource" >/dev/null 2>&1; do

If it produces problems on slow devices than imho the checks could be replaced by something like:
dd if="$cryptsource" of=/dev/null bs=1 count=1 >/dev/null 2>&1
Or anything more appropriate to test if a device is readable.

P.S.: If you ask me, this patch looks really ugly and needs a rewrite.

unggnu (unggnu) wrote :

The most weird thing I don't understand is that I have to enter the UUID of the encrypted Luks device in grub for the root tag which isn't known until the password is inserted. Even if I use /dev/mapper/root it is impossible to say which Luks partition is called root until encryption or am I wrong?
I guess the best thing is to have an extra kernel parameter which specifies the exact UUID of the Luks root device.
Btw. if you have a patch please upload it.

unggnu (unggnu) wrote :

Of course I mean decrypted Luks device and until decryption of the Luks partition.
Just for the records if I have a Luks device with an ext3 partition within the Luks partition has it's own UUID which can be read out directly and of course the ext3 has one which can't be read until the correct password is inserted. Later one is needed to mount root partition but the first one isn't specified in GRUB and of course needed for the Initramfs scripts or am I wrong?

gw0 (gw-launchpad) wrote :

I haven't written a patch. In my specific situation I am trying to use an encrypted swap (it would be the same for any other partition type) *without* LUKS (and without UUIDs - it doesn't really matter). And current code just freezes the boot process and waits for the timeout (because vol_id can't detect that this bunch of encrypted data represents a swap and therefore always returns error). My problem is only this useless waiting for timeout, because the detection mechanism of a readable device is wrong (uses dev_id that doesn't work on non-LUKS data). My temporary solution until someone will fix and possibly rewrite this code, is to be without swap (what just means no hibernating).

unggnu: No, /dev/mapper/root will get assigned exactly the (LUKS) partition you specified in /etc/crypttab. So you exactly know which container partition this is and also what it contains (different partitions mustn't have same UUIDs). I am always using direct device names, but in the case you described and if you insist on using UUIDs you should set the LUKS UUID in crypttab and make it map to root and than use /dev/mapper/root elsewhere where you want to access the decrypted partition.

After running your Initramfs contains data from crypttab, but if you insist you could also pass it via GRUB as a parameter.

unggnu (unggnu) wrote :

Thank you, you nailed it down. The problem was that I have configured the encrypted USB OS with my encrypted system so I couldn't use the Luks name "root" twice. I guess that's the reason why the initramfs script hasn't created the cryptsetup conf file. At least it worked with a Live CD finally when only the USB root partition was opened.

Changed in cryptsetup (Debian):
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.