03/09/25 - Self-Virtualisation¶
So I left it running last night backing up my Arch machine. I went into a NixOS live environment and created an image of my current machine in .qcow2 format. Backed out to Arch machine again to test the file.
I'm able to load the file with qemu but it gets stuck in seaBIOS saying "Booting from hard disk..."
Also if you are wondering why I am planning to virtualise on Nix, it is because tpye 1 hypervisors are expensive, and this is still my daily driver PC.
The aim is to learn skills that transfer, not make a working enterprise virtualisation server.
Cool I've gotten past that one. And it's actually loaded, my machine is virtualising itself. (Virtually)
Well it hasn't booted, but I know why. Arch is in emergency mode in the virtual machine because my fstab is telling it to reach my physical drives.
Thankfully I've had this issue before when I was messing around with encryption and edited my fstab to include the encrypted drives. Then booted later when I was done without the drive attached. Arch didn't like that.
I'm assuming I'll have to find a way to mount the virtual machine and edit the fstab to look for the virtual drive.
AI Summary of my terminal:
1. **Created the image.** From a NixOS live environment I imaged my Arch system disk to QCOW2 (`arch-phys-2025-09-02.qcow2`).
*(Stored at `/mnt/sda1/arch-phys-2025-09-02.qcow2`.)*
2. **First boot attempts (failed).**
* Legacy BIOS (SeaBIOS) looped at “Booting from hard disk…”. My host uses **UEFI** (GPT + systemd-boot), so BIOS couldn’t find a bootloader.
* Tried `if=sata` and hit `unsupported bus type 'sata'` on my QEMU build; switched to `ide`/`virtio` instead.
3. **Installed & located UEFI firmware.**
`edk2-ovmf` was installed but paths weren’t where I first looked. I found the **4MB OVMF** images here on Arch:
```
/usr/share/edk2/x64/OVMF_CODE.4m.fd
/usr/share/edk2/x64/OVMF_VARS.4m.fd
```
Copied the VARS template so I have a **writable NVRAM** file:
```
mkdir -p ~/.qemu
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd ~/.qemu/OVMF_VARS.arch.4m.fd
```
4. **Permissions gotchas.**
Opening the QCOW2 on `/mnt/sda1` as my user gave **Permission denied**; running QEMU with `sudo` worked. (Later fix is to adjust mount perms/ACLs.)
5. **fstab trap identified.**
Inside the VM, Arch dropped to **emergency mode** because my host `/etc/fstab` references physical disks that don’t exist in the VM. Fix is to **comment those lines** or mark them `nofail` inside the image.
Working QEMU command
This boots UEFI with virtio disk/net, KVM acceleration, and host SSH forwarded to port 2222:
```bash
sudo qemu-system-x86_64 \
-enable-kvm -cpu host -machine q35,accel=kvm \
-smp 4 -m 8G \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,file="$HOME/.qemu/OVMF_VARS.arch.4m.fd" \
-drive file=/mnt/sda1/arch-phys-2025-09-02.qcow2,if=virtio,format=qcow2 \
-nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
-display gtk -vga virtio -boot menu=on
```
Then I can `ssh -p 2222 user@127.0.0.1` once the VM is up.
Editing fstab
inside the image (to clear emergency mode)
Fast path using `qemu-nbd`:
```bash
1) Expose the QCOW2 as /dev/nbd0 sudo modprobe nbd max_part=8 sudo qemu-nbd --connect=/dev/nbd0 /mnt/sda1/arch-phys-2025-09-02.qcow2
2) Mount the root partition from the image (adjust pN after lsblk) lsblk /dev/nbd0 sudo mount /dev/nbd0p2 /mnt/img example
3) Edit fstab (comment non-root mounts or add 'nofail') sudo nvim /mnt/img/etc/fstab
4) Clean up sudo umount /mnt/img sudo qemu-nbd --disconnect /dev/nbd0 ```
Notes / takeaways
* Use **OVMF (UEFI)**, not SeaBIOS, when the guest disk was installed in UEFI mode.
* The `if=sata` shorthand isn’t available on my QEMU; **`virtio`** (or `ide`) works fine.
* Keep a **per-VM copy** of OVMF VARS so NVRAM writes don’t touch system files.
* Permission errors came from the mount options on `/mnt/sda1`; running as root was a quick workaround.
* Host-specific mounts in `fstab` will brick the VM boot; mark them `nofail` or remove them for the VM.
---
If you want, I can trim this further to match your earlier journal tone, or turn it into a tiny reproducible gist you can link from the entry.
Good to know I was right about the fstab.
My Actual Terminal:
Λ /mnt/sda1 sudo pacman -Syu edk2-ovmf qemu-full
Λ /mnt/sda1 pacman -Ql edk2-ovmf | grep -E 'OVMF_(CODE|VARS)\.fd'
find /usr/share -maxdepth 4 -type f -name 'OVMF_*fd' 2>/dev/null
/usr/share/edk2/x64/OVMF_CODE.4m.fd
/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd
/usr/share/edk2/x64/OVMF_VARS.4m.fd
/usr/share/edk2/ia32/OVMF_CODE.4m.fd
/usr/share/edk2/ia32/OVMF_CODE.secboot.4m.fd
/usr/share/edk2/ia32/OVMF_VARS.4m.fd
Λ /mnt/sda1 mkdir -p ~/.qemu
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd ~/.qemu/OVMF_VARS.arch.4m.fd
Λ /mnt/sda1 qemu-system-x86_64 \
-enable-kvm -cpu host -machine q35,accel=kvm \
-smp 4 -m 8G \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,file=$HOME/.qemu/OVMF_VARS.arch.4m.fd \
-drive file=/mnt/sda1/arch-phys-2025-09-02.qcow2,if=virtio,format=qcow2 \
-nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
-display gtk -vga virtio
qemu-system-x86_64: -drive file=/mnt/sda1/arch-phys-2025-09-02.qcow2,if=virtio,format=qcow2:
Could not open '/mnt/sda1/arch-phys-2025-09-02.qcow2': Permission denied
Λ /mnt/sda1 sudo !!
1 ↵
Λ /mnt/sda1 sudo qemu-system-x86_64 \
-enable-kvm -cpu host -machine q35,accel=kvm \
-smp 4 -m 8G \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,file=$HOME/.qemu/OVMF_VARS.arch.4m.fd \
-drive file=/mnt/sda1/arch-phys-2025-09-02.qcow2,if=virtio,format=qcow2 \
-nic user,model=virtio-net-pci,hostfwd=tcp::2222-:22 \
-display gtk -vga virtio
To Do:
Make a page about my dotfiles.