This morning I decided to test Qubes 4.2.0-RC4, and ran into an identical issue to you both. After doing some digging, I found what I believe to be the root of the problem, and following a quick (and dirty) workaround, I was able to install and use RC4 without any further issues.
The cause of the error appears to be twofold:
First, starting with RC3, this commit (Use partition layout on the iso as isohybrid did · QubesOS/qubes-builderv2@b170aeb · GitHub) switched to using a hybrid ISO format. To oversimplify, one side effect/feature of this new format is that it allows a device to be mounted directly, without having to specify a partition. As a result, when running fdisk -l
on your bootable media (I’ll use /dev/sdb
to represent the bootable USB device from here on), you’ll get output similar to the following:
Disk /dev/sdb: 28.9 GiB, 31029460992 bytes, 60604416 sectors
Disk model: USB DISK 3.0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
/dev/sdb1 * 1 12350159 12350159 5.9G 83 Linux
Notice how fdisk
displays the partition /dev/sdb1
? Despite this, when mounting the media (due to the hybrid ISO format), you actually don’t want to specify this partition, and instead use a command similar to the following: mount /dev/sdb /media
This brings me to the second factor causing the error, which is logic found (here) in Heads or (here) in Pureboot. If you look at the list_usb_storage()
function within the linked script (which is used during the “Boot from USB” process), you’ll see the following logic and comments:
sed "s|/sys/block|/dev|" |
while read b; do
# If the device has a partition table, ignore it and
# include the partitions instead - even if the kernel
# hasn't detected the partitions yet. Such a device is
# never usable directly, and this allows the "wait for
# disks" loop in mount-usb to correctly wait for the
# partitions.
# This check: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
# covers the case of a device without partition table but
# formatted as fat32, which contains a sortof partition table.
# this causes fdisk to not print the invalid partition table
# message and instead it'll print an empty table with header.
# In both cases the output is 5 lines: 3 about device info,
# 1 empty line and the 5th will be the table header or the
# unvalid message.
DISK_DATA=$(fdisk -l "$b")
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || [ $(echo "$DISK_DATA" | wc -l) -eq 5 ]; then
# No partition table, include this device
echo "$b"
else
# Has a partition table, include partitions
ls -1 "$b"* | awk 'NR!=1 {print $0}'
fi
done
Essentially, when enumerating USB storage devices to boot from, the above logic is checking if those devices contain valid partitions, and if they do, then it only returns those partitions as the valid targets to boot from. Although this may be more efficient in that it will often leave only one valid USB boot option, allowing the boot process to continue automatically (instead of having to stop and prompt the user to select which device/partition to boot from), it accidentally overlooks the possibility of a boot device using the hybrid ISO format.
To get around this issue, the quick and dirty fix I used was to edit the USB autoboot script (initrd/bin/usb-autoboot.sh · purism_next · firmware / PureBoot · GitLab) from within the recovery shell you get automatically dump into, so that it doesn’t rely on the output of list_usb_storage()
to select the boot device/partition. More specifically I used the command vi /bin/usb-autoboot.sh
to comment-out the line (found around line 31):
# list_usb_storage >/tmp/usb-autoboot-usb-storage
Then I added the following line directly below the line I just commented out, to manually specify the correct boot device (which in my case was /dev/sdb
):
printf '/dev/sdb\n' >/tmp/usb-autoboot-usb-storage
Note: You don’t have to worry too much about documenting the changes you make, as they aren’t persistent and the files will revert right back to their original state following a reboot.
Finally, just run the patched script via the following command, to successfully boot into the Qubes installer:
/bin/usb-autoboot.sh
Quick disclaimer: I am not a Qubes OS developer, and it’s completely possible that I’m wrong; what you’re seeing is just where the rabbit hole lead me
Final note: Sorry for the escaped links. As a new user it would not let me insert more than two links.