Creating BTRFS Subvolumes

There are several conditions for which the instructions for creating BTRFS sub-volumes can be crafted. For these instructions, we will presume the following conditions apply:

  • The operating system has been installed onto the storage device which either has been formatted into a btrfs file-system or has a partition with a BTRFS file-system format
  • The storage device, or its partition, that was formatted as BTRFS contains the root directory of the file-system and is encrypted via Linux Unified Key Setup (i.e., LUKS)
  • The operating system installed onto the storage device saves copies of the kernel image, or of kernel-booting programs, in a location called the initramfs archive
  • More generally, the operating system obeys the Linux file-system hierarchy standard
  • The sub-volumes to be created are at the root level of the file-system, e.g. /home

Under these conditions, the steps are as follows:

  1. Boot into a live linux environment that has btrfs installed, and get yourself on or make sure you are on a terminal application or TTY prompt that has access to or acts as a command-line interface by using bash interactively
  2. On there, log into root account to act as root user by running the script sudo -i
  3. Run the script fdisk -l or lsblk to find and identify the correct storage device or storage partition formatted in BTRFS
    • The partition containing the root directory is typically the largest in size and may be labeled “Linux filesystem¨ in the fdisk -l output
  4. Decrypt the LUKS root directory partition of the non-live storage by running the following script: cryptsetup open /dev/${device_type}${number} ${decrypted_name}
  5. Mount the LUKS decrypted partition, i.e. the unencrypted root directory partition, of the non-live storage onto an existing or created directory file path of your choosing that will act as the mount point on the live medium by running: mount /dev/mapper/${decrypted_name} ${mount_point}/
    • To create a new directory file path prior, run mkdir -p ${mount_point}
  6. Check to see if that partition mounted at ${mount_point}/ has any sub-volumes already by running: btrfs subvolume list ${mount_point}/
  7. Create desired sub-volumes by running: btrfs subvolume create ${mount_point}/${subvolume_name}
    • The sub-command above can take more than just one argument
  8. Recursively move files from the relevant, corresponding directory file path / directory file paths or already-extant sub-volumes of the desired data into those intended sub-volume(s) that were just created: mv -v ${subvol_or_dir_path}/* ${mount_point}/${subvolume_name}/
  9. Unmount the decrypted root directory partition: umount ${mount_point}. This is because you are going to mount the sub-volumes of that partition rather than the partition itself.
  10. Mount all the sub-volumes of the decrypted root directory partition, including the newly created ones: mount -o subvol=${subvolume_name} /dev/mapper/${decrypted_name} ${mount_point}
    • Run ls on ${mount_point} to make sure they are being or have been mounted: ls ${mount_point}
  11. Mount the other non-BTRFS formatted partitions as they should be; typically, the other partitions would be FAT32 or EXT4, so they would be mounted normally under the mount point the root directory partition was mounted on: mount /dev/${device_type}${number} ${mount_point}/${file_or_dir_path}
  12. Recursively bind directories dev, proc and sys onto equivalently named sub-directories of ${mount_point}, e.g. mount --rbind /proc ${mount_point}/proc
  13. Log into the mounted system by running: chroot ${mount_point} bash --login
  14. Run ls -lhA on the directory file paths for which BTRFS sub-volumes were made to make sure things have been moved properly
  15. Open a command line interface editor application to view and change the contents of the /etc/fstab file, e.g. nano /etc/fstab, and create entries for the BTRFS sub-volume mounting on/at boot. This will have the sub-volumes auto-mount at some point in the boot process.
  16. Finally, regenerate all kernel images or kernel-booting programs so as to register these changes on them. The script for this may vary depending on the Linux distribution operating system. On Fedora, it would be dracut --zstd --regenerate-all --force
  17. Run exit to log out of mounted system
  18. Run umount -R ${mount_point} to recursively unmount all sub-volumes and partitions
  19. Finally, re-encrypt the root directory partition on the target storage device by running cryptsetup close ${decrypted_name}
  20. You should now be free to reboot or shut down the system by running reboot or shutdown now