Skip to content

Instantly share code, notes, and snippets.

@poespas
Last active June 28, 2026 11:04
Show Gist options
  • Select an option

  • Save poespas/3596bac5e43177f31cbf47fc40b33412 to your computer and use it in GitHub Desktop.

Select an option

Save poespas/3596bac5e43177f31cbf47fc40b33412 to your computer and use it in GitHub Desktop.
Transform an physical disk into a VM

Transform an physical disk into a VM

Commands are ran from a liveUSB

Decrypt LUKS volume before imaging

If the disk is LUKS-encrypted, unlock it and image the decrypted device-mapper node. Encrypted data is random and won't compress; the decrypted stream (zeroed free space) compresses well over the network.

Find the LUKS partition:

lsblk -f

Unlock it (prompts for passphrase):

sudo cryptsetup luksOpen /dev/nvme0n1p2 decrypted

Then use /dev/mapper/decrypted as the source (if=) in the dd commands below instead of /dev/nvme0n1.

Notes:

  • This images only the LUKS container — no partition table or EFI/boot partition. If LVM is layered inside LUKS, the image is an LVM PV.
  • To make the VM boot, strip crypto references afterwards: remove the /etc/crypttab entry, regenerate the initramfs without the encrypt hook, and fix /etc/fstab/bootloader to point at the plaintext device.

Transfer raw image to external host

Compress over the network and extract on target. Faster: pigz -1 (all cores, speed over ratio), an AES-NI SSH cipher, and mbuffer to keep the gigabit pipe full (apt install mbuffer; drop it if unavailable).

sudo dd if=/dev/nvme0n1 bs=256M status=progress | pigz -1 -c | mbuffer -q -m 1G | ssh -c aes128-gcm@openssh.com [user]@[host] "gunzip -c > /mnt/disks/dev-nvme0n1.img"

Transfer compressed image (.gz) to external host

Keeps the archive compressed on the remote. For a smaller stored file raise the pigz level (e.g. -6) at the cost of speed.

sudo dd if=/dev/nvme0n1 bs=256M status=progress | pigz -1 -c | mbuffer -q -m 1G | ssh -c aes128-gcm@openssh.com [user]@[host] "cat > /mnt/disks/dev-nvme0n1.img.gz"

Convert disk to qcow2 format

$ qemu-img convert -f raw -O qcow2 /mnt/disks/dev-nvme0n1.img /mnt/disks/dev-nvme0n1.qcow2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment