This HowTo documents the steps I used on a
Fedora 17 x86_64 test machine to convert the root file system from Ext4 to Btrfs.
Anaconda (Fedora installer) doesn't support the creation or manipulation of Btrfs file systems in the graphical installer. Support for this is
slated for Fedora 18, at which time, Btrfs may become the default file system!
It is possible, however, to create Btrfs file systems at install time via
Kickstart.
The virtual machine was installed with
Fedora 17 x86_64 using default partitioning (LVM and Ext4) and selecting the Desktop profile.
If possible, create the partitions without LVM. (see section at the bottom for an example of this and UUID)
In the examples, the root file system is a logical volume: /dev/mapper/vg_f17vm-lv_root
Following the install and the initial boot, I rebooted using the
Fedora 17 x86_64 Live CD and chose the option to
Try Fedora.
I initially tried to perform the conversion using the Fedora 17 DVD and rescue mode, however the btrfs-convert utility isn't included. The live CD, however, includes the Btrfs utilities.
Convert EXT4 root
All of the steps are performed using the terminal, so open a Gnome Terminal and SU to root:
$ su -
Run fsck on the file system
# fsck.ext4 -f /dev/mapper/vg_f17vm-lv_root
Convert from ext4 to btrfs. The metadata stage can take a while on a large populated file system (on an 1.5TB ext4 file system with approx 500GB of data, a good mix of large and small files, this step took about 1.5 hours)
# btrfs-convert /dev/mapper/vg_f17vm-lv_root
creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
Mount the freshly converted btrfs root file system so that we can make some modifications (fstab, SELinux)
# mkdir /mnt/btrfs
# mount -t btrfs /dev/mapper/vg_f17vm-lv_root /mnt/btrfs
Edit fstab to change the root file system from ext4 to btrfs
# vi /mnt/btrfs/etc/fstab
#/dev/mapper/vg_f17vm-lv_root ext4 defaults 1 1
/dev/mapper/vg_f17vm-lv_root btrfs defaults 1 1
Force the system to automatically relabel the SELinux context for the root file system during boot.
# touch /mnt/btrfs/.autorelabel
NOTE: In my test, the Fedora 17 system would hang with systemd library permissions errors prior to getting to the SELinux auto relabel step.
To work around this, I rebooted back into the Live CD and change the SELinux policy to "permissive" from "enforcing". During the next boot, the permission errors went by and then the SELinux autorelabel ran to completion.
# vi /mnt/btrfs/etc/selinux/config
#SELINUX=enforcing
SELINUX=permissive
The Btrfs conversion process created a subvolume of the old ext4 file system. The following commands mount the subvolume and file system, demonstrating the power of Btrfs.
# mkdir /mnt/{ext2_saved,ext4}
# mount -t btrfs -o subvol=ext2_saved /dev/mapper/vg_f17vm-lv_root /mnt/ext2_saved
# mount -t ext4 -o loop,ro /mnt/ext2_saved/image /mnt/ext4
The contents of the ext4 and btrfs mounts should be identical, sans the changes made above to fstab and config.
It's possible to roll back the conversion by first unmounting the file systems and then rolling it back using the -r switch
# umount /dev/mapper/vg_f17vm-lv_root
# btrfs-convert -r /dev/mapper/vg_f17vm-lv_root
If you decide to stay with btrfs, you can delete the subvolume snapshot of the original ext4 system
# btrfs subvolume delete /mnt/btrfs/ext2_saved
Reboot into the installed OS and the system should perform the relabel and then come up with your shiny new btrfs file system.
To make things really cool, install the
yum-plugin-fs-snapshot Yum plugin. This plugin will create a btrfs subvolume of your root file system prior to installing updates. The end result, you can roll back from yum updates. Test that you can mount the snapshot of the ext4 file system
Once the system is up and running, don't forget to set the SELinux policy back to "enforcing"
Issues:
- It appears that some of the systemd services attempt to start prior to the SELinux .autorelabel step. This results in permission errors that prevent the system from booting. Temporarily change the SELinux policy to "permissive" to work past this.
- During boot, you may see errors logged by the systemd-fsck service failing for lv_root due to missing fsck.btrfs. I suspect that the btrfs-progs rpm failed to create a symlink of fsck.btrf pointing to /usr/sbin/btrfsck
systemd-fsck[858]: fsck: fsck.btrfs: not found
systemd-fsck[858]: fsck: error 2 while executing fsck.btrfs for /dev/mapper/vg_f17vm-lv_root
Convert Luks Encrypted EXT4 home
If your file system is encrypted with Luks, you'll have the additional step of decrypting the file system prior to running the conversion
# cryptsetup luksOpen /dev/mapper/vg_f17vm-lv_home luks_home
# fsck.ext4 -f /dev/mapper/luks_home
# btrfs-convert /dev/mapper/luks_home
creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
Converting Non LVM Ext4 and UUID in /etc/fstab
If you don't use LVM (recommended based on everything I've ready, since it's not needed for btrfs), your /etc/fstab may mount the partitions using the UUID. After converting the file system to btrfs, the UUID will change.
These steps demonstrate how to convert the root file syste, a non LVM ext4 partition, /dev/sda2.
# fsck.ext4 -f /dev/sda2
# btrfs-convert /dev/sda2
creating btrfs metadata.
creating ext2fs image file.
cleaning up system chunk.
conversion complete.
Identify the UUID using blkid (can also look under /dev/disk/by-uuid
# blkid /dev/sda2
/dev/sda2: UUID="56d1e02b-3120-44c3-b8f8-d3289012e447" UUID_SUB="13f7b26b-42b1-41bb-a9dc-c928ad033f6d" TYPE="btrfs"
# mkdir /mnt/btrfs
# mount -t btrfs /dev/sda2 /mnt/btrfs
Edit fstab to change the root file system from ext4 to btrfs and replace the UUID with the new UUID
# vi /mnt/btrfs/etc/fstab
#UUID=e14bd8d6-ac8a-4f15-8169-f0a9bdf4b69e / ext4 defaults 1 1
UUID=56d1e02b-3120-44c3-b8f8-d3289012e447 / btrfs defaults 1 1
UUID=f4cdf95d-66eb-4428-960d-23b289ffb63e /boot ext4 defaults 1 2
Chroot to the real root file system and update grub.cfg using grub2-mkconfig
# mount -o bind /dev /mnt/btrfs/dev
# mount -o bind /proc /mnt/btrfs/proc
# mount -o bind /sys /mnt/btrfs/sys
# mount /dev/sda1 /mnt/btrfs/boot
# chroot /mnt/btrfs
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.4.3-1.fc17.x86_64
Found initrd image: /boot/initramfs-3.4.3-1.fc17.x86_64.img
Found linux image: /boot/vmlinuz-3.3.4-5.fc17.x86_64
Found initrd image: /boot/initramfs-3.3.4-5.fc17.x86_64.img
Warning: Please don't use old title `Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' for GRUB_DEFAULT, use `Advanced options for Fedora Linux>Fedora Linux, with Linux 3.3.4-5.fc17.x86_64' (for versions before 2.00) or `gnulinux-advanced-/dev/sda2>gnulinux-3.3.4-5.fc17.x86_64-advanced-/dev/sda2' (for 2.00 or later)
done
Exit out of the chroot and unmount the file systems
# exit
# umount /mnt/btrfs/boot
# umount /mnt/btrfs/dev
# umount /mnt/btrfs/proc
# umount /mnt/btrfs/sys
# umount /mnt/btrfs
Reboot and you should be good to go. The selinux relabeling can take a while!
References: