Cannot boot live initrd due to dmsquash-live-root.sh dash syntax error

Hello,

First of all, thanks for all the hard work you all put into this distro. It looks great :).

I would like to report a problem with the dracut version that I found in OMA. This error is possibly present in the upstream dracut version as well, but I haven’t taken the time to investigate that yet.

  • OpenMandriva Lx version: Lx3.02 Build 1180

  • Desktop environment (KDE, LXQT…): Default KDE that comes with OMA

  • Description of the issue (screenshots if relevant):

For OEM development purposes, I have generated a custom initrd with dracut dracut-045-3-omv2015.0.x86_64.rpm. However, I cannot boot the system with that initrd, as I get the following error on my screen:

dracut-initqueue[327]: /sbin/dmsquash-live-root: 169: /sbin/dmsquash-live-root: Syntax error: "(" unexpected (expecting "fi")

And after a timeout I am taken to the dracut rescue shell. Here’s a screenshot of the problem:

  • Relevant informations (hardware involved, software version, logs or output…):

Detailed version information of dracut:

# rpm -q --info dracut
Name        : dracut                       Relocations: (not relocatable)
Version     : 045                               Vendor: OpenMandriva
Release     : 3                             Build Date: sáb 29 abr 2017 17:38:56 -03
Install Date: seg 19 jun 2017 11:08:10 -0   Build Host: 10cores.openmandriva.org
Group       : System/Base                   Source RPM: dracut-045-3.src.rpm
Size        : 783792                           License: GPLv2+
Signature   : RSA/SHA1, qua 10 mai 2017 09:46:51 -03, Key ID 180922d8bf81de15
Packager    : tpg <tpgxyz@gmail.com>
URL         : https://dracut.wiki.kernel.org/
Summary     : Next generation initrd image generator
Architecture: x86_64
Description :
Dracut contains tools to create a bootable initramfs for 2.6 Linux kernels.
Unlike existing implementations, dracut does hard-code as little as possible
into the initramfs. Dracut contains various modules which are driven by the
event-based udev. Having root on MD, DM, LVM2, LUKS is supported as well as
NFS, iSCSI, NBD, FCoE with the dracut-network package.

Procedure to reproduce the problem:

  1. generate the initrd with dmsquash live and dash shell:

    dracut /boot/initrd_live.img --force --add-drivers ‘isofs iso9660 ext4 sata_sis ata_piix pata_atiixp sata_via sata_nv ahci loop dm_snapshot usbcore usb_storage dm_mod dm_crypt’ --modules ‘dracut-systemd systemd-initrd base dm dmsquash-live terminfo rootfs-block kernel-modules resume dash i18n’

  2. Boot OMA Lx3.02 and press ‘e’ to edit GRUB’s boot options. Edit kernel options and include the following options at the end (the rd.live.dir=oem does not need to exist, as the error occurs before any actual use of that dir):

    linux … rd.live.image rd.live.dir=oem

  3. Edit the initrd to use the one that was just created

     initrd /boot/initrd_live.img 
    
  4. Press F10 to boot
    

I would upload a screenshot of this grub editing, but I can’t because I am a new user.

Main symptom: You should end up with the following error on the screen:

dracut-initqueue[327]: /sbin/dmsquash-live-root: 169: /sbin/dmsquash-live-root: Syntax error: "(" unexpected (expecting "fi")

Possible root cause: I did investigate this for a while, and I believe that I have found the root cause of the problem:

  1. dracut aims to be POSIX compliant, and therefore uses /bin/dash is /bin/sh whenever possible, as stated in their wiki main page: Home · dracutdevs/dracut Wiki · GitHub

  2. If we observe the dmsquash-live-root.sh (located at /usr/lib/dracut/modules.d/90dmsquash-live/dmsquash-live-root.sh) script at line 169, this is what is happening there:

     163 if [ -z "$setup" -o -n "$readonly_overlay" ]; then
     164     if [ -n "$setup" ]; then
     165         warn "Using temporary overlay."
     166     elif [ -n "$devspec" -a -n "$pathspec" ]; then
     167         [ -z "$m" ] &&
     168             m='  Unable to find a persistent overlay; using a temporary one.'
     169         m=($'\n' "$m" $'\n'
     170            '     All root filesystem changes will be lost on shutdown.'
     171            $'\n' '        Press any key to continue')
     172         echo -e "\n\n\n${m[*]}\n\n\n" > /dev/kmsg
    
  3. I’ve created a tiny script to try to reproduce this syntax error:

     #!/bin/dash
     
     if /bin/true ; then
     	[ -z "$m" ] &&
     		m='  Unable to find a persistent overlay; using a temporary one.'
     	m=($'\n' "$m" $'\n'
     	'     All root filesystem changes will be lost on shutdown.'
     	$'\n' '        Press any key to continue')
     
     	echo $m
     fi
    

I get the following error after executing this code:

./dracut_shell_test.sh: 6: ./dracut_shell_test.sh: Syntax error: "(" unexpected (expecting "fi")

As a quick and dirty workaround, I changed lines 169-171 of the script to look like this:

169         m=$'\n'"$m"$'\n''     All root filesystem changes will be lost on shutdown.'$'\n''        Press any key to continue')

And then generated the initrd again. After this change, my live initrd could boot normally. I hope all of this helps in solving the problem for other users.

Thanks!

Felipe

1 Like

Huh? Are you try to boot the Lx 3.02 ISO to ‘Live’ with a custom made initrd? What happens if you just boot it to ‘Live’ with the initrd that is already on the ISO?

What I’m getting at:
If I understand what you are trying to do then you’ll probably need to build a new ISO with the new initrd.

Edit: I’m no expert at all on this but aren’t you trying to write something on a squasfs that is read only?

Thanks @fsrechia for your interesting report.

I used the following code (I only changed the line starting with echo)

#!/bin/dash

if /bin/true ; then
	[ -z "$m" ] &&
		m='  Unable to find a persistent overlay; using a temporary one.'
	m=($'\n' "$m" $'\n'
	'     All root filesystem changes will be lost on shutdown.'
	$'\n' '        Press any key to continue')

	echo -e ${m[*]}
fi

Here the results of my tests:

$ sh test.sh
Unable to find a persistent overlay; using a temporary one. All root filesystem changes will be lost on shutdown. Press any key to continue
bash-4.4$ bash test.sh
Unable to find a persistent overlay; using a temporary one. All root filesystem changes will be lost on shutdown. Press any key to continue
bash-4.4$ dash test.sh
test.sh: 6: test.sh: Syntax error: "(" unexpected (expecting "fi")

So the code is incompatible with dash only.

Please @fsrechia could you fill a bug report about this?

2 Likes

Hi @ben79 !

Thanks for the quick response.

Yes you did understand this correctly. We build a custom ISO which boots to a custom oem-installer that we have. This ISO is built directly based on OpenMandriva’s repositories, which we mirror locally and use to build a root filesystem based on our selection of packages.

Later on in the process we build a read-only squashfs image, and a custom ISO. I don’t know details of the inner workings of the overlay mechanism used by dracut, but we let the dmsquash-live module handle the temporary ramdisk overlay required for regular operation of the live installer ISO. :slight_smile:

The main reason I was using a regular Lx3.02 system to reproduce the problem was to make it easier for you all to reproduce it, if necessary. There is really no point in generating this custom initrd for desktop usage with Lx3.02.

@mandian thanks for the feedback, I’ll file a bug report there as soon as possible.

Best wishes,

Felipe

2 Likes

Here’s a solution using printf dunno whether printf is acceptable in dracus but it is is POSIX compliant and much cleaner for this sort of thing.

#!/bin/dash

if /bin/true ; then
    [ -z "$m" ] &&
        m='  Unable to find a persistent overlay; using a temporary one.'
        m=$(printf '%s\n'  "$m" "     All root filesystem changes will be lost on shutdown." /
 "        Press any key to continue"

    echo "$m"
fi

I just checked the dracut source and printf is used all over the place.

EDIT: code formatting ~jcl

I corrected this it was wrong new dracut version should now be available in testing repo

Mandian showing my ignorance here but how do you paste formatted code as you have.

You may use Preformatted text (</>) button or Ctrl+Shift+C. You may also use `` for inline preformatted text and four spaces at the beginning of each line for long text (I used this method).

Thanks a lot for the help, everyone. Just placing these links here for future reference:

best wishes,
Felipe

1 Like