The original steps were mostly correct, but for some reason, I kept ending up with a corrupt initrd. Summarized below are all the steps that should result in a working scenario for anyone interested in doing the same:
- Create a virtual machine as desired.
- Install Linux using desired partition layout and make all desired changes. In this case, it consists of a BTRFS boot partition and a LUKS encrypted BTRFS root partition. Other layouts should work if care is taken to properly update references during the transfer.
- Boot the previous VM using a Linux live ISO so that you can access the installed system offline.
- Attach a USB flash drive to the VM for the transfer. (Note: You can create a
dd
image of the installed drive and save outside the VM, which you can then use from a normal Linux system.)
- Prepare the flash drive partitions.
- Option:
dd
the original image onto the flash drive and skip to step 7, then to step 10. (Note: It appears to have been necessary in my case to recreate the partitions for an unknown reason where blkid
was unable to enumerate the UUID of the boot BTRFS partition.)
- Option: Create new partitions using the same UUIDs as the original ones. Assuming
/dev/sda1
for boot and /dev/sda2
for root.
- For BTRFS boot partition:
sudo mkfs.btrfs -f -L BOOT -U <original UUID> /dev/sda1
- For LUKS root partition:
sudo cryptsetup --uuid=<original UUID> luksFormat /dev/sda2
- Map root partition:
sudo cryptsetup --allow-discards open --type luks /dev/sda2 flash_luks
- Format root using BTRFS:
sudo mkfs.btrfs -f -L ROOT -U <original UUID> /dev/mapper/flash_luks
- Option: Create new partitions using new UUIDs. Repeat the same steps as Option 2, but remove arguments relating to UUID/uuid. Take note of the new UUIDs using
sudo blkid
.
- Mount original image partitions.
- Create read-only loop-back devices for each partition:
sudo kpartx -ar <flash dd image file>
. Assuming kpartx attaches to loop0.
- Create dirs for mount points:
sudo mkdir -p /media/orig_boot /media/orig_root
- Boot:
sudo mount -r /dev/mapper/loop0p1 /media/orig_boot
- Root LUKS:
sudo cryptsetup -r open --type luks /dev/mapper/loop0p2 orig_luks
- Root:
sudo mount -r /dev/mapper/orig_luks /media/orig_root
- Mount flash drive partitions. Assuming
/dev/sda1
for boot.
- Create dirs for mount points:
sudo mkdir -p /media/flash_boot /media/flash_root
- Boot:
sudo mount -t btrfs -o nodiratime,noatime,compress=zlib,discard,ssd,space_cache /dev/sda1 /media/flash_boot
- Root (assuming it was already mapped using cryptsetup earlier):
sudo mount -t btrfs -o relatime,compress=zlib,discard,ssd,space_cache /dev/mapper/flash_luks /media/flash_root
- Copy contents:
- Boot:
sudo rsync -aEXS --progress /media/orig_boot/ /media/flash_boot
- Root:
sudo rsync -aEXS --progress /media/orig_root/ /media/flash_root
- Unmount original image.
- Root:
sudo umount /media/orig_root
- Root LUKS:
sudo cryptsetup close orig_luks
- Boot:
sudo umount /media/orig_boot
- kpartx:
sudo kpartx -d <flash dd image file>
- Chroot into flash drive.
- Bind
/sys
: sudo mount --bind /sys /media/flash_root/sys
- Bind
/dev
: sudo mount --bind /dev /media/flash_root/dev
- Bind
/dev/pts
: sudo mount --bind /dev/pts /media/flash_root/dev/pts
- Bind
/proc
: sudo mount --bind /proc /media/flash_root/proc
- Unmount boot:
sudo umount /media/flash_boot
- Remount inside root:
sudo mount -t btrfs -o relatime,compress=zlib,discard,ssd,space_cache /dev/sda1 /media/flash_root/boot
- Chroot:
sudo chroot /media/flash_root
- Update
/etc/fstab
.
- Boot line:
UUID=<btrfs boot uuid> /boot btrfs nodiratime,noatime,compress=zlib,discard,ssd,space_cache 0 2
- Root line:
UUID=<btrfs root uuid> / btrfs nodiratime,noatime,compress=zlib,discard,ssd,space_cache 0 1
- Update
/etc/crypttab
: flash_luks UUID=<luks root uuid> none discard,luks
- Install
btrfs-tools
(if not installed): sudo apt-get install btrfs-tools
- Update boot stuff.
- Initrd (makes use of fstab/crypttab to decide what is needed prior to mount and to prompt for LUKS password on boot):
sudo update-initramfs -u -k all
(Note: You can recreate all initrds using sudo update-initramfs -c -k all
, but I didn't try that to be sure.)
- Grub (makes use of fstab to update kernel boot options and mount correct partitions):
sudo update-grub
- Install grub to MBR (assuming
/dev/sda
): sudo grub-install --recheck /dev/sda
- Exit chroot:
exit
- Unmount everything.
sudo umount /media/flash_root/boot
sudo umount /media/flash_root/proc
sudo umount /media/flash_root/dev/pts
sudo umount /media/flash_root/dev
sudo umount /media/flash_root/sys
sudo umount /media/flash_root
sudo cryptsetup close flash_luks