2

TL;DR: How can I boot a squashfs partition from initramfs with a predictable partition name? /dev/sda2 won't work because the device names get reordered randomly and sometimes it will boot from the wrong partition.


We use a custom installation of Gentoo that looks like this:

/dev/sda1: /boot   ext4 (unencrypted)
/dev/sda2: /       squashfs (unencrypted)
/dev/sda3: /home   ext4 (dm-crypt)
/dev/sda4: -       swap

We made a custom initramfs script that mounts the root partition and a tmpfs on top of it as an overlay filesystem. We used this guide and it looks like this:

#!/bin/busybox sh
mount -t proc none /proc
mount -t sysfs none /sys

# Mount the root filesystem.
mount -t squashfs -o ro /dev/sda2 /mnt/overlay
# (some stuff to set up the overlay with tmpfs is done here)

# Clean up. 
umount /proc
umount /sys

# Boot the real thing.
exec switch_root /mnt/overlay /sbin/init

It boots normally and everything works as long as this is the only disk on the system, since /dev/sda2 is always the root partition in a system with only one disk.

We're working on an automatic update system, as this custom install will ship to other cities and ideally our customers should be able to update their system by simply inserting a USB stick and waiting for the update to be done. Updates over the Internet are not an option. Keeping our data safe is a top priority and we believe the partition scheme we chose is safe enough for our needs, though we're open to new ideas if it means solving our issue:

The USB stick update system is a copy of the original Gentoo install and uses exactly the same partition scheme. However, the initramfs script in the USB stick gets confused and usually picks the root of the original install, not the root of the USB updater. Obviously, the update program (which is on the root of the USB stick) will never run like this.

We tried replacing /dev/sda2 in the initramfs script of the USB stick with

  1. /dev/disk/by-id/usb*part2, which already works in the GRUB2 menu but doesn't work from the initramfs script because /dev/disk doesn't exist at this point (by the way, why does it exist in GRUB?)
  2. $(findfs PARTUUID="partid-of-usb-squashfs-root"), didn't work
  3. $(findfs UUID="x"), which would work if squashfs partitions had a filesystem UUID (this does work with ext4 and other filesystems)

The guide suggests using devtmpfs or mdev to populate /dev at init time, but we don't know how this helps because /dev/disk seems to be udev's job and starting a devtmpfs from the initramfs script doesn't seem to help.

How can we get predictable/persistent partition names in an initramfs script when the root partition doesn't have a filesystem UUID?

It's a bit hard to change our partition scheme and we don't want our squashfs root or our /home partition to be visible for a casual Windows user, but we'll try to do something if there's something else that allows us to reliably boot from the same partition every time, like LVM or something else we haven't thought of.

1

LVM is a candidate in this case, but adds complexity in the bootloader/initramfs instead.

Can you gaurentee there is only one squashfs filesystem present as a block devices? If so, then you could use findfs TYPE=squashfs to find the correct root filesystem.

However, you note that your USB key is nearly identical, so also contains a squashfs filesystem. Therefore you need to start looking for alternative places to put tracing information. Your /boot volume looks like a good candidate; on the USB key it can have something that flags it as a removable device; on the hard drive it can have something that flags it as a real install.

  • The USB installer has the same partition scheme as the custom install, TYPE=squashfs didn't work for that reason. – satori Mar 28 '17 at 17:14
  • Yes, that's what I noted in the third paragraph. – robbat2 Mar 28 '17 at 19:17
1

There was no need to rely on any special tools for this.

Knowing the squashfs partition is always second in the partition scheme is enough: just set the UUID of the first partition of the pendrive, use $(findfs UUID=first-pendrive-partition) and do sed s/1/2/ on the result.

The system always detects the correct partition now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.