Just how convenient would it be, if Proxmox containers would use a BTRFS subvolume as a rootfs? Snapshot, Backups, etc.–everything would be super easy.

But, installing Proxmox on a BTRFS disk is not enough, one has to use the command line to create a LXC container and specify BTRFS as the root filesystem. Well, I learned about that, when ten containers were already up and running.

This post explores how to migrate the rootfs of an existing LXC container from a raw image (inside: ext4 filesystem) to a btrfs subvolume. It assumes that Proxmox is installed with the BTRFS disk option, so YMMV.

Step-by-step

If your container already exists, migration of its rootfs is actually easy and straightforward. In the following, replace XXX with the container ID.

  1. Shut down the LXC container.
  2. Find your current rootfs. In case it resides in local-btrfs you should find it under /var/lib/pve/local-btrfs/images/XXX/vm-XXX-disk-0/disk.raw. This raw image file contains the ext4 root filesystem of your container.
    $ RAW_DISC_PATH=/var/lib/pve/local-btrfs/images/XXX/vm-XXX-disk-0/disk.raw
    
  3. Mount the root filesystem (this forum thread discusses how to do that in detail).
    $ losetup --partscan /dev/loopXXX ${RAW_DISC_PATH}
    $ RAW_DISC_MNT=/var/lib/pve/local-btrfs/images/XXX/mnt-raw
    $ mount /dev/loopXXX ${RAW_DISC_MNT}
    
  4. Create the replacement btrfs filesystem.
    $ BTRFS_SUBVOL=/var/lib/pve/local-btrfs/images/XXX/subvol-XXX-disk-0.subvol
    $ btrfs subvol create ${BTRFS_SUBVOL}
    
  5. Copy the file contents from the mounted raw disk to the BTRFS subvolume, and then unmount the raw disk.
    $ rsync -avz ${RAW_DISC_MNT}/* ${BTRFS_SUBVOL}/
    $ umount ${RAW_DISC_MNT}
    
  6. Update the config /etc/pve/lxc/XXX.conf.
    -rootfs: local-btrfs:XXX/vm-XXX-disk-0.raw,size=6G
    +rootfs: local-btrfs:XXX/subvol-XXX-disk-0.subvol,size=6G
    
  7. Start up your container and clean up the old root disk.

And everything should just work :)