DEV Community

vast cow
vast cow

Posted on

Procedure for Changing the rootfs of Rocky Linux 9 to F2FS

Procedure for Changing the rootfs of Rocky Linux 9 to F2FS

When changing the root filesystem of Rocky Linux 9 to F2FS, it is difficult to complete the process using only the standard installer. In practice, the realistic workflow is to first perform a normal Rocky 9 installation using ext4, XFS, or similar, then boot from a Live USB, back up the rootfs, recreate it as F2FS, and restore it.

This article organizes the procedure under the following assumptions:

  • /boot is a separate partition from the rootfs
  • /boot remains ext4 or XFS
  • Only / is changed to F2FS
  • ELRepo’s kernel-lt is used instead of the standard Rocky 9 kernel
  • The same UUID as the original rootfs is specified when running mkfs.f2fs
  • If the system does not boot, recovery is performed by chrooting from an Ubuntu Live USB

ELRepo is a repository that provides kernels, filesystem drivers, and similar packages for Enterprise Linux, and kernel-lt is provided as a long-term support kernel. When trying F2FS root on Rocky/RHEL 9 systems, assuming the use of an ELRepo kernel rather than the standard kernel is practical. (Elrepo)


1. Basic Policy

The final configuration will be as follows.

/boot      ext4 or XFS
/boot/efi  vfat
/          f2fs
Enter fullscreen mode Exit fullscreen mode

The reason for not making /boot F2FS is simple: to reduce uncertainty around GRUB and early boot. If only the rootfs is F2FS, GRUB reads the kernel and initramfs from /boot as usual, and the rootfs is mounted by the F2FS driver inside the initramfs.


2. Install Rocky 9 Normally

First, install Rocky Linux 9 normally.

At this point, the rootfs may be ext4, XFS, or similar.

Example partition layout:

/dev/nvme0n1p1  /boot/efi
/dev/nvme0n1p2  /boot
/dev/nvme0n1p3  /
Enter fullscreen mode Exit fullscreen mode

What matters is keeping /boot separate from /.


3. Set SELinux to permissive

After conversion to F2FS, there is a possibility of running into issues involving SELinux labels or extended attributes. Therefore, set SELinux to permissive before the work.

sudo vi /etc/selinux/config
Enter fullscreen mode Exit fullscreen mode
SELINUX=permissive
Enter fullscreen mode Exit fullscreen mode

Reboot after making the change.

sudo reboot
Enter fullscreen mode Exit fullscreen mode

After booting, check the status.

getenforce
Enter fullscreen mode Exit fullscreen mode
Permissive
Enter fullscreen mode Exit fullscreen mode

4. Install ELRepo’s kernel-lt

Use ELRepo’s kernel-lt instead of the standard Rocky 9 kernel.

sudo dnf install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm
sudo dnf --enablerepo=elrepo-kernel install kernel-lt
Enter fullscreen mode Exit fullscreen mode

Caution is required if Secure Boot is enabled. According to ELRepo’s explanation, kernel-ml and kernel-lt are not signed with a Secure Boot key. In a Secure Boot environment, you must either disable Secure Boot or sign the kernel yourself and register it with MOK. (Elrepo)

Reboot.

sudo reboot
Enter fullscreen mode Exit fullscreen mode

Select ELRepo’s kernel-lt in GRUB, then verify after booting.

uname -r
Enter fullscreen mode Exit fullscreen mode

Confirm that the system has booted with a kernel version containing elrepo.

Also check whether the F2FS module can be used.

sudo modprobe f2fs
grep f2fs /proc/filesystems
Enter fullscreen mode Exit fullscreen mode

If this fails, you should not proceed with converting the rootfs to F2FS.


5. Create a dracut Configuration to Include the F2FS Driver

Once the rootfs is F2FS, the F2FS driver is needed during the initramfs stage. Therefore, persist the dracut configuration.

sudo tee /etc/dracut.conf.d/90-f2fs-root.conf >/dev/null <<'EOF'
add_drivers+=" f2fs "
EOF
Enter fullscreen mode Exit fullscreen mode

In dracut.conf, kernel modules specified in add_drivers can be added to the initramfs. Specify the module name without .ko. (Ubuntu Manpages)

You may also use force_drivers if necessary.

sudo tee /etc/dracut.conf.d/90-f2fs-root.conf >/dev/null <<'EOF'
force_drivers+=" f2fs "
EOF
Enter fullscreen mode Exit fullscreen mode

Like add_drivers, force_drivers includes the module, but it is a setting intended to have it modprobed at an earlier stage. (Ubuntu Manpages)

Rebuild the initramfs.

sudo dracut -f /boot/initramfs-$(uname -r).img $(uname -r)
Enter fullscreen mode Exit fullscreen mode

Check its contents.

lsinitrd /boot/initramfs-$(uname -r).img | grep f2fs
Enter fullscreen mode Exit fullscreen mode

It is sufficient if f2fs.ko is included.


6. Boot from a Live USB

From here, boot using an Ubuntu Live USB or similar and perform the work.

First, check the disk layout.

sudo lsblk -f
sudo blkid
Enter fullscreen mode Exit fullscreen mode

Here, assume the following example:

/dev/nvme0n1p1  /boot/efi
/dev/nvme0n1p2  /boot
/dev/nvme0n1p3  /
Enter fullscreen mode Exit fullscreen mode

The rootfs is assumed to be /dev/nvme0n1p3.


7. Record the UUID of the rootfs

Under this policy, the same UUID as the original rootfs is specified when running mkfs.f2fs.

First, save the current UUID.

OLD_UUID=$(sudo blkid -s UUID -o value /dev/nvme0n1p3)
echo "$OLD_UUID"
Enter fullscreen mode Exit fullscreen mode

Use this UUID when creating the F2FS filesystem as well.


8. Back Up the rootfs Before Conversion

Mount the rootfs before conversion.

sudo mkdir -p /mnt/src
sudo mount /dev/nvme0n1p3 /mnt/src
Enter fullscreen mode Exit fullscreen mode

Mount the backup destination. Example:

sudo mkdir -p /mnt/backup
sudo mount /dev/sdX1 /mnt/backup
Enter fullscreen mode Exit fullscreen mode

When backing up with tar, make sure not to lose SELinux contexts, xattrs, ACLs, or ownership information.

sudo tar \
  --one-file-system \
  --xattrs --xattrs-include='*' \
  --acls \
  --selinux \
  --numeric-owner \
  --sparse \
  -cpf /mnt/backup/rocky-root.tar \
  -C /mnt/src .
Enter fullscreen mode Exit fullscreen mode

This backup is a logical backup of the rootfs.

As additional insurance, it is also a good idea to back up the entire pre-conversion partition using partclone or similar. A partclone backup serves as insurance for “restoring the original ext4/XFS rootfs if the conversion fails.”

After backing up, unmount it.

sudo umount /mnt/src
Enter fullscreen mode Exit fullscreen mode

9. Create the rootfs as F2FS

Now recreate the rootfs partition as F2FS.

If your version of mkfs.f2fs supports specifying a UUID, specify the original UUID.

sudo mkfs.f2fs -f -l rocky-root -U "$OLD_UUID" /dev/nvme0n1p3
Enter fullscreen mode Exit fullscreen mode

After creation, check whether the UUID is the same.

sudo blkid /dev/nvme0n1p3
Enter fullscreen mode Exit fullscreen mode

Expected state:

UUID="<OLD_UUID>" TYPE="f2fs"
Enter fullscreen mode Exit fullscreen mode

Whether mkfs.f2fs -U can be used may depend on the version of f2fs-tools, so check in advance.

mkfs.f2fs -h
Enter fullscreen mode Exit fullscreen mode

If you can keep the same UUID, you can avoid making major changes to root=UUID=... in BLS/GRUB. However, you must change the filesystem type in fstab to F2FS.


10. Restore the rootfs

Mount the rootfs that was converted to F2FS.

sudo mkdir -p /mnt/dst
sudo mount -t f2fs /dev/nvme0n1p3 /mnt/dst
Enter fullscreen mode Exit fullscreen mode

Restore from the tar archive.

sudo tar \
  --xattrs --xattrs-include='*' \
  --acls \
  --selinux \
  --numeric-owner \
  --same-owner \
  --sparse \
  -xpf /mnt/backup/rocky-root.tar \
  -C /mnt/dst
Enter fullscreen mode Exit fullscreen mode

Sync.

sudo sync
Enter fullscreen mode Exit fullscreen mode

11. Edit /etc/fstab

Edit the restored fstab.

sudo vi /mnt/dst/etc/fstab
Enter fullscreen mode Exit fullscreen mode

Change the rootfs line to F2FS.

Example:

UUID=<OLD_UUID>  /  f2fs  defaults,noatime  0  0
Enter fullscreen mode Exit fullscreen mode

Because the UUID is kept the same in this procedure, the UUID itself does not need to be changed.

However, this must be changed:

ext4 or xfs → f2fs
Enter fullscreen mode Exit fullscreen mode

If prioritizing recoverability, set the final pass number to 0 at first.

UUID=<OLD_UUID>  /  f2fs  defaults,noatime  0  0
Enter fullscreen mode Exit fullscreen mode

If you can reliably include fsck.f2fs in the initramfs and operate it that way, review this later.


12. Mount /boot and Check the BLS Entries

Since /boot is a separate partition, be sure to mount it.

sudo mount /dev/nvme0n1p2 /mnt/dst/boot
Enter fullscreen mode Exit fullscreen mode

In a UEFI environment, also mount the EFI System Partition.

sudo mount /dev/nvme0n1p1 /mnt/dst/boot/efi
Enter fullscreen mode Exit fullscreen mode

Check the BLS entries.

grep -R "root=" /mnt/dst/boot/loader/entries/*.conf
Enter fullscreen mode Exit fullscreen mode

Since the UUID is kept the same, root=UUID=... can basically remain unchanged.

However, it is clearer to add rootfstype=f2fs.

Chroot and add it with grubby.

sudo mount --rbind /dev /mnt/dst/dev
sudo mount --make-rslave /mnt/dst/dev
sudo mount -t proc proc /mnt/dst/proc
sudo mount -t sysfs sysfs /mnt/dst/sys
sudo mount -t tmpfs tmpfs /mnt/dst/run

sudo chroot /mnt/dst /bin/bash
Enter fullscreen mode Exit fullscreen mode

Run the following inside the chroot.

grubby --update-kernel=ALL --args="rootfstype=f2fs"
Enter fullscreen mode Exit fullscreen mode

On RHEL 9 systems, boot entry kernel command lines can be changed with grubby. Red Hat documentation also shows grubby --update-kernel=ALL --args=... as a method for adding kernel parameters to all boot entries. (Red Hat Documentation)

Check the result.

grep -R "root=" /boot/loader/entries/*.conf
grep -R "rootfstype" /boot/loader/entries/*.conf
Enter fullscreen mode Exit fullscreen mode

13. Regenerate the initramfs Inside the chroot

When chrooting from a Live USB, do not use uname -r.

This is because uname -r returns the kernel version of the Live USB environment.

Check the Rocky-side kernel versions in /lib/modules.

ls /lib/modules
Enter fullscreen mode Exit fullscreen mode

Target the ELRepo kernel.

KVER=$(ls /lib/modules | grep elrepo | tail -n 1)
echo "$KVER"
Enter fullscreen mode Exit fullscreen mode

Prioritizing recoverability, first create a broader initramfs.

dracut -f \
  --no-hostonly \
  --force-drivers "f2fs" \
  "/boot/initramfs-${KVER}.img" \
  "${KVER}"
Enter fullscreen mode Exit fullscreen mode

dracut is a tool for creating initramfs images; it collects the necessary tools/files from the installed system and builds the initramfs. (GitHub)

Check it.

lsinitrd "/boot/initramfs-${KVER}.img" | grep f2fs
Enter fullscreen mode Exit fullscreen mode

Confirm that f2fs.ko is included.


14. Schedule an SELinux Relabel

Even if xattrs and SELinux contexts were preserved with tar, it is safer to schedule a relabel on the first boot.

Inside the chroot:

touch /.autorelabel
Enter fullscreen mode Exit fullscreen mode

A relabel will run after the first boot.


15. Exit the chroot and Reboot

Exit the chroot.

exit
Enter fullscreen mode Exit fullscreen mode

Unmount.

sudo sync
sudo umount -R /mnt/dst
Enter fullscreen mode Exit fullscreen mode

Reboot.

sudo reboot
Enter fullscreen mode Exit fullscreen mode

In GRUB, select ELRepo’s kernel-lt.


16. Check After Booting

If the system boots successfully, check whether the rootfs is F2FS.

findmnt -no SOURCE,FSTYPE,OPTIONS /
Enter fullscreen mode Exit fullscreen mode

Expected output:

/dev/nvme0n1p3 f2fs ...
Enter fullscreen mode Exit fullscreen mode

Also check the kernel.

uname -r
Enter fullscreen mode Exit fullscreen mode

Confirm that it is the ELRepo kernel.

grep f2fs /proc/filesystems
Enter fullscreen mode Exit fullscreen mode

SELinux can remain permissive for now.

getenforce
Enter fullscreen mode Exit fullscreen mode

If there are no problems, switch it back to enforcing as needed.

sudo vi /etc/selinux/config
Enter fullscreen mode Exit fullscreen mode
SELINUX=enforcing
Enter fullscreen mode Exit fullscreen mode

Check again after rebooting.

getenforce
Enter fullscreen mode Exit fullscreen mode

Recovery Procedure If the System Does Not Boot

If the system does not boot after converting to F2FS, recover by chrooting from an Ubuntu Live USB.

1. Boot from a Live USB and Check

sudo lsblk -f
sudo blkid
Enter fullscreen mode Exit fullscreen mode

Check whether the rootfs is recognized as F2FS.

sudo file -s /dev/nvme0n1p3
Enter fullscreen mode Exit fullscreen mode

2. Mount the rootfs, boot, and EFI

sudo mkdir -p /mnt/sysroot
sudo mount -t f2fs /dev/nvme0n1p3 /mnt/sysroot
Enter fullscreen mode Exit fullscreen mode

Mount /boot.

sudo mount /dev/nvme0n1p2 /mnt/sysroot/boot
Enter fullscreen mode Exit fullscreen mode

For UEFI:

sudo mount /dev/nvme0n1p1 /mnt/sysroot/boot/efi
Enter fullscreen mode Exit fullscreen mode

This is important.

If you run dracut without mounting /boot, the initramfs will be created in the empty directory inside the rootfs, not in the actual /boot.


3. chroot

sudo mount --rbind /dev /mnt/sysroot/dev
sudo mount --make-rslave /mnt/sysroot/dev
sudo mount -t proc proc /mnt/sysroot/proc
sudo mount -t sysfs sysfs /mnt/sysroot/sys
sudo mount -t tmpfs tmpfs /mnt/sysroot/run
Enter fullscreen mode Exit fullscreen mode
sudo chroot /mnt/sysroot /bin/bash
Enter fullscreen mode Exit fullscreen mode

4. Check fstab

cat /etc/fstab
Enter fullscreen mode Exit fullscreen mode

Confirm that the rootfs is F2FS.

UUID=<OLD_UUID>  /  f2fs  defaults,noatime  0  0
Enter fullscreen mode Exit fullscreen mode

5. Check the BLS Entries

grep -R "root=" /boot/loader/entries/*.conf
grep -R "rootfstype" /boot/loader/entries/*.conf
Enter fullscreen mode Exit fullscreen mode

If the UUID is kept the same, root=UUID=... can basically remain unchanged.

However, if rootfstype=f2fs is missing, add it.

grubby --update-kernel=ALL --args="rootfstype=f2fs"
Enter fullscreen mode Exit fullscreen mode

6. Explicitly Specify the Target Kernel and Re-run dracut

Do not use uname -r here either.

ls /lib/modules
Enter fullscreen mode Exit fullscreen mode

Select the ELRepo kernel.

KVER=$(ls /lib/modules | grep elrepo | tail -n 1)
echo "$KVER"
Enter fullscreen mode Exit fullscreen mode

Rebuild the initramfs.

dracut -f \
  --no-hostonly \
  --force-drivers "f2fs" \
  "/boot/initramfs-${KVER}.img" \
  "${KVER}"
Enter fullscreen mode Exit fullscreen mode

Check it.

lsinitrd "/boot/initramfs-${KVER}.img" | grep f2fs
Enter fullscreen mode Exit fullscreen mode

7. Schedule an SELinux Relabel

touch /.autorelabel
Enter fullscreen mode Exit fullscreen mode

8. Exit the chroot and Reboot

exit
Enter fullscreen mode Exit fullscreen mode
sudo sync
sudo umount -R /mnt/sysroot
sudo reboot
Enter fullscreen mode Exit fullscreen mode

Select ELRepo kernel-lt in GRUB.


Common Causes of Failure

Symptom Cause
unknown filesystem type 'f2fs' The F2FS module is not included in the initramfs
VFS: Unable to mount root fs The rootfs specification, initramfs, or kernel module is incorrect
UUID=... does not exist The UUID changed, or the UUID was specified incorrectly
Drops into emergency shell fstab, root specification, initramfs, or SELinux issue
Does not boot with standard kernel The Rocky 9 standard kernel side does not have the F2FS root module, or it is not in the initramfs
Still not fixed after running dracut in chroot The initramfs was created without mounting /boot
dracut -f $(uname -r) fails The Live USB kernel version is being used

Summary

The procedure for changing the rootfs of Rocky Linux 9 to F2FS is safer when done as follows.

1. Install Rocky 9 normally with /boot as a separate partition
2. Set SELinux to permissive
3. Install ELRepo kernel-lt
4. Boot with kernel-lt and check the f2fs module
5. Persistently add f2fs to dracut
6. Boot from an Ubuntu Live USB
7. Back up the rootfs with tar, including xattrs/ACLs/SELinux
8. Record the original rootfs UUID
9. Specify the original UUID when running mkfs.f2fs
10. Restore the rootfs
11. Change the rootfs type in /etc/fstab to f2fs
12. Add rootfstype=f2fs to the BLS entries
13. Explicitly specify the target kernel inside the chroot and regenerate dracut
14. Create /.autorelabel
15. Boot with ELRepo kernel-lt
Enter fullscreen mode Exit fullscreen mode

The following four points are especially important.

- Always keep /boot separate
- Include f2fs.ko in the initramfs
- Confirm that the UUID remains the same after mkfs.f2fs
- If the system does not boot, recover using Live USB + chroot + dracut
Enter fullscreen mode Exit fullscreen mode

If you keep the UUID the same as before, you can avoid changing root=UUID=..., which makes the work considerably simpler. However, the filesystem type in /etc/fstab and the F2FS module in the initramfs must be configured correctly.

Top comments (0)