losetup upgrade results in boot failure

May 15, 20264 min. read

Alpine Linux just recently upgraded losetup from util-linux, which is used for mounting subpartitions on Android devices. This upgrade removes a command line flag that was used in the initramfs (-v).

Due to the initramfs still trying to use that option despite it being removed, losetup will complain about it and do nothing, leading to boot failure:

losetup: unrecognised option: v

This was fixed in postmarketos-initramfs 3.10.2. If you upgraded your system recently and are not running that version, do not reboot until you upgrade to postmarketos-initramfs 3.10.2. As of writing, it is queued for building in build.postmarketos.org. Check that page to know when you can upgrade. (UPDATE: it has finished building and is now available in the binary repos)

Once it's available, you can run:

sudo apk upgrade -a

If you rebooted and your device doesn't boot anymore, below are steps to recover.

Recovery

Thanks to debug-shell, you can recover from this somewhat easily, though the steps are quite involved.

Preparation

Edit the init_functions.sh file at /. The modifications are not permanent, it is just to allow us to properly mount the rootfs:

vi init_functions.sh

Edit line 365 to replace it from:

        local losetup_args="--show -Pfv --direct-io=on"

to:

        local losetup_args="--show -Pf --direct-io=on"

(remove the -v flag)

Then edit line 415:

                                [ -n "$SUBPARTITION_LOOP" ] && losetup -vd "$SUBPARTITION_LOOP"

to:

                                [ -n "$SUBPARTITION_LOOP" ] && losetup -d "$SUBPARTITION_LOOP"

(also remove the -v flag, basically)

Save and exit, then:

. init_functions.sh
mount_subpartitions

Mounting the rootfs

If your rootfs is encrypted:

cryptsetup open $PMOS_ROOT root
mount /dev/mapper/root /sysroot/

If not, then simply run:

mount $PMOS_ROOT /sysroot/

Fixing things

Afterwards, we'll need to chroot to the rootfs we just mounted.

Mount the boot partition inside the rootfs:

mount_boot_partition /sysroot/boot/ "rw"

Then run:

cd /sysroot/
mount -t proc /proc proc/
mount -t sysfs /sys sys/
mount --rbind /dev dev/

chroot /sysroot/ /bin/sh

You are now inside your installation. From there, do the same modifications to the init_functions.sh as you did above:

vi /usr/share/initramfs/init_functions.sh

Save the changes.

boot-deploy hacks

NOTE: If your device does not need to have a kernel flashed in some boot partition, you do not need to do this. Check /usr/share/deviceinfo/deviceinfo to tell (look fordeviceinfo_flash_methodset to eitherfastboot,fastboot-bootpart,heimdall-bootimgorheimdall-isorec`.) If you are unsure, ask in chat!

boot-deploy will not flash the kernel in a chroot. We can hack around that to have our new initramfs get picked up on next boot.

Edit boot-deploy-functions.sh:

vi /usr/share/boot-deploy/boot-deploy-functions.sh

And remove the following at lines 916-919:

        if is_in_chroot; then
                log_arrow "Not flashing boot in chroot"
                return 0
        fi

Finishing

You can now finally run:

mkinitfs

The output should be something like this:

01:07:58.090641 Generating for kernel version: 7.1.0-rc1-sdm845
01:07:58.090734 Output directory: /boot
01:07:58.090738 == Generating initramfs ==
01:07:58.090742 - Using compression format zstd with level "fast"
01:07:58.090765 - Searching for directories specified in /usr/share/mkinitfs/dirs
01:07:58.090799 -- Creating directories from: /usr/share/mkinitfs/dirs/00-initramfs-base.dirs
01:07:58.090852 - Searching for directories specified in /etc/mkinitfs/dirs
01:07:58.090877 - Searching for file lists from /usr/share/mkinitfs/files
01:07:58.090906 -- Including files from: /usr/share/mkinitfs/files/00-device-xiaomi-beryllium-modules.files
01:07:58.090958 -- Including files from: /usr/share/mkinitfs/files/00-initramfs-base.files
01:07:58.091994 -- Including files from: /usr/share/mkinitfs/files/10-wireless-regdb.files
01:07:58.092085 -- Including files from: /usr/share/mkinitfs/files/postmarketos-base.files
01:07:58.092150 - Searching for file lists from /etc/mkinitfs/files
01:07:58.092176 - Searching for hook scripts from /usr/share/mkinitfs/hooks
01:07:58.092194 - Searching for hook scripts from /etc/mkinitfs/hooks
01:07:58.092207 - Searching for hook scripts from /usr/share/mkinitfs/hooks-cleanup
01:07:58.092213 -- Unable to find dir, skipping...
01:07:58.092223 - Searching for hook scripts from /etc/mkinitfs/hooks-cleanup
01:07:58.092228 -- Unable to find dir, skipping...
01:07:58.092317 - Searching for kernel modules from /usr/share/mkinitfs/modules
01:07:58.092341 -- Including modules from: /usr/share/mkinitfs/modules/00-default.modules
01:07:58.132277 -- Including modules from: /usr/share/mkinitfs/modules/00-device-xiaomi-beryllium.modules
01:07:58.146099 - Searching for kernel modules from /etc/mkinitfs/modules
01:07:58.146911 - Searching for file lists from /usr/share/mkinitfs/files-extra
01:07:58.147446 -- Including files from: /usr/share/mkinitfs/files-extra/00-initramfs-extra-base.files
01:07:58.153329 -- Including files from: /usr/share/mkinitfs/files-extra/30-postmarketos-bootsplash.files
01:07:58.170747 -- Including files from: /usr/share/mkinitfs/files-extra/30-unl0kr.files
01:07:58.214342 - Searching for file lists from /etc/mkinitfs/files-extra
01:07:58.214496 - Searching for hook scripts from /usr/share/mkinitfs/hooks-extra
01:07:58.214581 - Searching for hook scripts from /etc/mkinitfs/hooks-extra
01:07:58.215064 - Searching for kernel modules from /usr/share/mkinitfs/modules-extra
01:07:58.215174 -- Including modules from: /usr/share/mkinitfs/modules-extra/00-default-extra.modules
01:07:58.225489 - Searching for kernel modules from /etc/mkinitfs/modules-extra
01:07:58.863307 initramfs completed in: 0.77s
01:07:58.863378 == Using boot-deploy to finalize/install files ==
==> Running hooks
==> kernel: device-tree blob operations
==> kernel: appending device-tree qcom/sdm845-xiaomi-beryllium-tianma
==> initramfs: creating boot.img
Parsing /usr/lib/kernel-cmdline.d/00-base.conf
Parsing /usr/lib/kernel-cmdline.d/20-plymouth.conf
Parsing /usr/lib/kernel-cmdline.d/50-device-xiaomi-beryllium.conf
==> systemd-boot: found '/usr/lib/systemd/boot/efi/systemd-bootaa64.efi'
Parsing /usr/lib/kernel-cmdline.d/00-base.conf
Parsing /usr/lib/kernel-cmdline.d/20-plymouth.conf
Parsing /usr/lib/kernel-cmdline.d/50-device-xiaomi-beryllium.conf
==> Checking free space at /boot
... OK!
==> Installing: /boot/initramfs
==> Installing: /boot/sdm845-xiaomi-beryllium-tianma.dtb
==> Installing: /boot/boot.img
==> Installing: /boot/EFI/BOOT/BOOTAA64.EFI
==> Installing: /boot/loader/entries/pmos.conf
==> Not flashing boot when booting with EFI
01:08:01.445469 boot-deploy completed in: 2.58s
01:08:01.448627 mkinitfs completed in: 3.36s

Afterwards, you can then exit the chroot and reboot:

exit
reboot

Next steps

In your now booting installation, it is recommended to upgrade to get the latest postmarketos-initramfs package that contains the fix:

sudo apk upgrade -a

If you followed the section about modifying boot-deploy, it is recommended to undo them with:

sudo apk fix boot-deploy

Getting help

If you need help recovering your installation, please reach out to us in our realtime Matrix/IRC channels.

Also see