# Predictable device name for squashfs partition in initramfs

## satori420

I've already posted this question somewhere else but you guys might have an answer for it, since it's a Gentoo install after all.

I've got a /boot partition, a squashfs root partition and a custom initramfs. The script looks like this:

```
#!/bin/busybox sh

 rescue_shell() {

    echo "$1 went wrong"

}

 

 

# Mount the /proc and /sys filesystems.

mount -t proc none /proc

mount -t sysfs none /sys

 

 

# Mount the root filesystem.

mount -t squashfs -o ro /dev/sda2 /mnt/root || rescue_shell "squash_root"

mount -t tmpfs tmpfs /mnt/temp || rescue_shell "tmpfs"

mkdir /mnt/temp/upper || rescue_shell "upper"

mkdir /mnt/temp/work || rescue_shell "work"

mount -t overlay overlay -o lowerdir=/mnt/root,upperdir=/mnt/temp/upper,workdir=/mnt/temp/work /mnt/merge || rescue_shell "overlay"

 

# Clean up.

umount /proc

umount /sys

 

# Boot the real thing.

exec switch_root /mnt/merge /sbin/init
```

It boots normally when there's only one disk connected to the computer. What I'd like to do is boot another Gentoo install from a pendrive while keeping the other disk connected. The pendrive install also has a squashfs root, but replacing /dev/sda2 with /dev/sdb2 boots the wrong root most of the time.

squashfs doesn't have a filesystem UUID, /dev/disk/by-id is not available at initramfs time and $(findfs PARTUUID="xxxx") didn't find anything. Is there anything else I can do? I can install LVM or copy other programs to the initramfs if it's necessary.

----------

## frostschutz

There is no rescue shell in your rescue shell, just an echo of one...

You should probably add devtmpfs mount to it. https://wiki.gentoo.org/wiki/Custom_Initramfs#devtmpfs

Then the UUID stuff should start working as well. If it does not maybe a problem in your kernel, does it have built in support for all your storage, partition types, filesystems, ...?

----------

## satori420

You're right about the shell, I forgot to add the exec sh line to the code snippet, but it's in the compiled kernel already and I get dropped to a shell when anything fails.

It's not a device problem because everything works when there's only one disk in the system. squashfs boots normally and the tmpfs overlay is mounted properly. I can use /dev/sda2 in that case. The problem comes up when there are two disks connected and the /dev/sd{ab} names get reordered randomly. Sometimes /dev/sda2 is the partition we need, sometimes it's the second partition of the device we don't need and nothing boots. That's why we need an UUID in this case.

I already added devtmpfs with 

```
mount -t devtmpfs none /dev
```

and when I'm in the rescue shell, ls /dev shows the standard stuff: /dev/sd*, /dev/tty and other devices. There is no /dev/disk directory, which I assume is correct because I think this is a feature of udev that is obviously not available in the initramfs. It would be great if it were though.

The obvious choice is to replace /dev/sda2 with the UUID of the partition, but squashfs doesn't have a filesystem UUID   :Mad: 

When I run findfs from a desktop install, it has the option to use UUID=, LABEL= or PARTUUID=. As far as I know, squashfs doesn't have a UUID or a label, so PARTUUID is the only choice. But busybox's findfs can't handle PARTUUIDs at all.

I found this squashfs bug report. Looks like I'm not the only one facing this issue. Any temporary workaround would be greatly appreciated.

----------

## Ant P.

 *satori420 wrote:*   

> When I run findfs from a desktop install, it has the option to use UUID=, LABEL= or PARTUUID=. As far as I know, squashfs doesn't have a UUID or a label, so PARTUUID is the only choice. But busybox's findfs can't handle PARTUUIDs at all.

 

You could try something like:

```
busybox blkid | busybox awk -F': ' '/TYPE="squashfs"/ { print $1 }'
```

----------

## satori420

That command does indeed detect squashfs partitions. I think I forgot to mention that both the pendrive and the disk have a squashfs filesystem in the second partition, so it doesn't work in my case. Sorry I didn't mention this important detail before.

I think it would be good enough if there were some way of detecting which device is the pendrive and which is the hard disk at initramfs time, at least for this case.

----------

## frostschutz

 *Quote:*   

> You're right about the shell, I forgot to add the exec sh line to the code snippet, but it's in the compiled kernel already and I get dropped to a shell when anything fails.

 

Not sure how that is supposed to work ... sounds like you have a different initramfs in your kernel than what you believe... or still passing an initrd file in your bootloader which overwrites the builtin initramfs.

What is the full output of the blkid, does it not include UUID, LABEL, whatever?

----------

## satori420

No, please don't worry about that, I've made many changes to the custom initramfs script and they are reflected in each reboot, I just made a mistake copying and pasting the script here. The exec sh is there in the original script.

Here's the output of blkid after I get dropped to a shell:

```

/dev/sdb3: UUID="20984a91-..." TYPE="crypto_LUKS"

/dev/sdb1: UUID="bb109ad1-..." TYPE="ext2"

/dev/sda3: UUID="5ae4dad3-..." TYPE="crypto_LUKS"

/dev/sda2: LABEL="working_root " UUID="f9faca2c-..." TYPE="ext4"

/dev/sda1: LABEL="working_boot" UUID="d8441ba9-..." TYPE="ext2"

```

I don't know why the squashfs root of the USB drive (usually /dev/sdb2) doesn't appear here, the drivers are installed and it boots normally when there's only one disk in the computer. We did change the squashfs magic numbers but we made sure to change them both in the kernel sources and in the mksquashfs sources, so that shouldn't be a problem. mount -t squashfs works fine in the modified kernel.

I can mount /dev/sdb2 just fine and do the rest of the bootstrapping manually, it works as expected. The device names still get reordered randomly though.

I'm thinking of getting the SHA512sum of all the /dev/sd*2 partitions at initramfs time and booting the one that matches the checksum I need, but it would be much better if there were a non-hackish solution instead.

----------

## frostschutz

 *satori420 wrote:*   

> We did change the squashfs magic numbers but we made sure to change them both in the kernel sources and in the mksquashfs sources, so that shouldn't be a problem.

 

Uuuh.

What about all the other sources? In this case particularly... busybox/util-linux/volume_id/squashfs.c ?

----------

## Ant P.

Try converting the disks to GPT? You might need hybrid MBR for the one you boot from but that should at least get you real PARTUUIDs everywhere.

----------

## satori420

Um, we hadn't changed that source to use our magic numbers yet.

I connected both the disk and the pendrive and now busybox blkid shows

```

/dev/sdb3: UUID="20984a91-..." TYPE="crypto_LUKS"

/dev/sdb2: TYPE="squashfs"

/dev/sdb1: UUID="bb109ad1-..." TYPE="ext2"

/dev/sda3: UUID="5ae4dad3-..." TYPE="crypto_LUKS"

/dev/sda2: TYPE="squashfs"

/dev/sda1: UUID="d8441ba9-..." TYPE="ext2" 

```

Last post has the wrong output and doesn't show the two squashfs partitions, I accidentally used the development disk instead of the final squashfs disk.

I hope this makes my problem clear, busybox findfs can't use PARTUUIDs (the findfs in util-linux can use them though) and I don't know which one is the right one.

----------

## frostschutz

Okay, so squashfs just isn't informative in any way  :Sad: 

I guess you'll just have to look for another UUID on the same disk that blkid is able to find and then change the partition number of the returned device.

So use UUID to find /dev/sdx1 then change to /dev/sdx2.

If you're looking for hacks you could also use this method https://wiki.archlinux.org/index.php/Dm-crypt/Swap_encryption#UUID_and_LABEL

Put a bogus filesystem on it which provides the UUID and then mount squashfs at offset 1M. This will give you a slight overhead though (device mapping or loop device required). Speaking of device mappings you could just use LVM to properly name partitions.

Or you could take the Live CD isoloop approach, Live CDs mount all sorts of filesystem during boot in order to find their ISO image files which is located anywhere [on an usb stick or whatever], so you could iterate over all squashfs, mount them, then check if the file you're looking for is inside or not. (basically create a file UUID in each squashfs)

Or go with PARTUUID after all (no findfs, just mount PARTUUID=xyz /mnt/where)

----------

## satori420

I never thought of using another UUID, that's much simpler than what I had in mind. It works now, I just replaced

```

mount -t squashfs -o ro /dev/sda2 /mnt/root || rescue_shell "squash_root" 

```

with

```

mount -t squashfs -o ro $(findfs UUID="bb109ad1-..." | sed "s/1/2/") /mnt/root || rescue_shell "squash_root" 

```

Thank you!

----------

## frostschutz

Glad it works.

Another option would be to fix the drive order after all, if the drives are connected through different channels (one onboard, another usb, or similar) this could be done by loading drivers in a specific order, alternatively you could go through the /sys/bus/platform/drivers/…/{bind,unbind} interface and unbind the disks from the driver, and then re-bind them in the desired order. That way you could make a specific sata port (or whatever) always be /dev/sda and nothing else.

----------

## satori420

Yes, they are connected through different channels. I had no idea you could force the order devices are named in, that's some incredibly useful info you've got there.

----------

