Support my work ♥

Unpacking a QEMU qcow2 image on a physical disk

Two thinkpads connected with Ethernet

I have an old laptop with a slowish HDD so I did the smart thing and installed an operating system inside a QEMU+KVM on my modern machine with much more RAM and a SSD.

Also, the WiFi drivers for that particular model are not included in most operating systems, so until they are fetched via Ethernet the device is pretty helpless.

Lucky me: NetworkManager has a connection sharing feature that takes care of all the annoying details like IPv4 NAT, DNS forwarding and DHCPv4. I wish it would work that easy with IPv6 too.

Now that I am finished, how do I get the image over to the physical drive?

Attempt one: Sending through Pipe (does not work)

QEMU comes with this handy conversion tool that should work like the real dd:

qemu-img dd -f qcow2 -O raw bs=4M if=hda.qcow2 of=- | ssh root@ 'dd bs=4M status=progress of=/dev/sda'

Sadly, no. According to this bug report from 2009:

This is technically not possible. Given the formats involved, the file is not read/written linearly

Or as filesystem experts like to say: Both input and output files need to be seekable and a pipe is not.

Attempt two: sshfs (does not work)

Instead of writing the file in a local buffer which would require a lot of free disk space, why not:

  1. boot the target machine with Kali Linux or Knoppix
  2. start sshd on the machine, give root a password and enable root login with password in /etc/ssh/sshd_config
  3. mount it like this: sshfs root@ /run/media/target_host/

Now we have access to seekable files.

Sadly, sshfs does not support device files. So we can not write to /dev/sda*

Attempt three: sshfs back (works)

So at this point it is just a matter of willpower. A battle of wits if you will. 😉

First, install sshd on my main machine and make sure that it does not start on boot automatically. Starting it on my machine with sudo systemctl start sshd.

Second, with Kali already running on the target machine: 1. apt update to get the latest packages 2. apt install sshfs qemu-block-extra 3. Mount backwards like this: sshfs user@ /mnt/ 4. Finally, apply the image to the disk with: qemu-img dd -f qcow2 -O raw bs=4M if=/mnt/hda.qcow2 of=/dev/sda

After a quite substantial wait (roughly 45min, praise gigabit Ethernet) the complete image was transferred 🎉

What a time to be alive!