The 812GB Hiding in Plain Sight
Date: November 18, 2025 Issue: VM won’t boot after hypervisor migration Root Cause: Hypervisor compatibility (KVM → Proxmox) Actual Solution: 812GB of free space I didn’t know I had
The Setup
I’ve been building Argo OS — a custom Gentoo distribution — inside a KVM virtual machine on my main workstation. The VM was working perfectly, but running it on my daily driver meant competing for resources.
Simple plan: migrate the VM to my Proxmox server. Free up my workstation. Done.
The Migration Attempt
Step 1: Copy the QCOW2 disk image to Proxmox.
rsync -avP gentoo-btrfs.qcow2 [email protected]:/tank/vms/
qm disk import 200 /tank/vms/gentoo-btrfs.qcow2 tank
Step 2: Boot the VM.
PXE-E53: No boot filename received
Booting from Hard Disk...
Nothing. Just a blinking cursor.
Problem 1: Disk Not Attached
Classic rookie mistake. qm disk import imports the disk but doesn’t attach it.
qm config 200
# boot: order=net0
# unused0: tank:vm-200-disk-0 ← There it is, unused
qm set 200 --scsi0 tank:vm-200-disk-0
qm set 200 --boot order=scsi0
Okay, now boot.
Problem 2: Missing UEFI
Still hung at “Booting from Hard Disk…”
qm config 200 | grep -i "bios\|efi"
# Nothing
The VM was UEFI-based, but Proxmox defaults to BIOS. UEFI boot entries live in firmware NVRAM — they don’t transfer between hypervisors.
qm set 200 --efidisk0 tank:vm-200-efi,efitype=4m,pre-enrolled-keys=1
qm set 200 --bios ovmf
Boot again.
Problem 3: The Graphics Nightmare
GRUB loaded! Progress. Selected the kernel.
Then the screen became modern art. Garbled colors. Corrupted text. Random pixels.
I tried everything:
nomodesetkernel parametervga=off- Different display types
- Serial console fallback
Nothing worked.
The Root Cause
This wasn’t a configuration problem. This was a hardware abstraction layer mismatch.
- KVM environment: Specific virtual hardware (virtio devices, ACPI tables, CPU flags)
- Proxmox QEMU: Different virtual hardware emulation
The Gentoo kernel was compiled for KVM’s virtual environment. It had drivers and configurations specific to that hardware abstraction. Proxmox presented different virtual hardware, and the kernel couldn’t initialize it.
I could spend days debugging graphics drivers. Or…
The Pivot
“Is this how distro developers would do it?”
No. Real distro developers don’t migrate VMs. They:
- Build reproducibly from source
- Use binary package repositories
- Version control configurations
- Deploy fresh to each target
I was treating VM images like pets. I should be treating them like cattle.
The Discovery
While planning a fresh install on my workstation, I ran fdisk -l:
Device Start End Sectors Size Type
nvme0n1p1 2048 1050623 1048576 512M EFI System
nvme0n1p2 1050624 1083391 32768 16M Linux filesystem
nvme0n1p3 1083392 735160319 734076928 350G Microsoft basic data
nvme0n1p4 735160320 1258143743 522983424 249.4G Microsoft basic data
nvme0n1p5 1258143744 1259458559 1314816 642M Windows recovery
nvme0n1p6 1259458560 1259491327 32768 16M Microsoft reserved
nvme0n1p8 2963310592 3907029134 943718543 450G Linux filesystem
# Wait. p6 ends at 1,259,491,327. p8 starts at 2,963,310,592.
# That's a gap of... 1.7 billion sectors?
812 gigabytes. Unallocated. On my main NVMe drive.
I’d been so focused on the 450GB openSUSE partition and the Windows partitions that I never noticed a massive gap between them.
The New Plan
Forget the VM. Fresh install on bare metal.
Proposed layout in the 812GB gap:
├── p7: 200G Gentoo root (/)
├── p9: 8G Gentoo swap
└── Remaining: ~604GB (future expansion)
Why this is better:
- ✅ Native hardware (NVIDIA GPU, actual CPU features)
- ✅ No hypervisor overhead
- ✅ No compatibility issues
- ✅ Binary packages from testbed server
- ✅ Configurations from Git
The testbed machine compiles everything. My workstation just consumes pre-built packages.
The Architecture Shift
Before:
┌─────────────────────────────────────┐
│ Workstation │
│ ├── openSUSE (daily driver) │
│ └── KVM VM (Gentoo Golden Image) │
│ └── Compiles @world │
│ └── Eats CPU/RAM │
└─────────────────────────────────────┘
After:
┌─────────────────────────────────────┐
│ Testbed (Tau-Ceti-Lab) │
│ └── Bare metal Gentoo │
│ └── Compiles @world continuously │
│ └── Serves binpkgs via HTTP │
└──────────────┬──────────────────────┘
│
│ HTTP: binary packages
│ Git: configurations
▼
┌─────────────────────────────────────┐
│ Workstation (Galileo-Outpost) │
│ ├── openSUSE (legacy, shrinking) │
│ └── Gentoo (fresh install) │
│ └── Pulls configs from Git │
│ └── Pulls binpkgs from testbed │
│ └── Never compiles locally │
└─────────────────────────────────────┘
Lessons Learned
-
Check for unallocated space before assuming you need to shrink partitions. 812GB was hiding in plain sight.
-
VM migration between hypervisors is non-trivial. UEFI variables, hardware abstraction, drivers — they’re all tied to the source environment.
-
Sometimes the right answer is to start fresh. I could have spent days debugging graphics drivers. Instead, I designed a better architecture.
-
Distro development has best practices for a reason. HTTP repositories, Git for configs, reproducible builds — these exist because VMs don’t scale.
-
Bare metal can be simpler than VMs. No hypervisor compatibility, faster compilation, real hardware support.
What I Built
# On testbed - set up package repository
emerge -av nginx
# Configure to serve /var/cache/binpkgs
# On workstation - configure to consume
echo 'PORTAGE_BINHOST="http://10.42.0.194"' >> /etc/portage/make.conf
echo 'FEATURES="${FEATURES} getbinpkg"' >> /etc/portage/make.conf
# Install using binary packages
emerge -av --getbinpkg @world
No compilation on the workstation. Everything pre-built on the testbed. Install time: minutes instead of hours.
The Irony
I spent 4 hours trying to fix a VM migration.
The solution was already on my disk, in the form of 812GB of free space I forgot existed.
Sometimes the bug isn’t in the code. It’s in the assumption that you understood the problem.
The discovery of 812GB of hidden free space led to a complete architecture redesign. What started as a troubleshooting session became a lesson in professional distro development practices.