How to Change root partition from EXT4 to XFS without changing boot disk

I have a quite a problem where my new VPS provider didn’t allow me to change boot disk so I have to be clever. The problem is my VPS provider doesn’t give me disk format so I’m stuck with EXT4 but I want it to be XFS since it has better interoperability with quotas, so I need to do crazy things to change it.
To do this we still need a secondary disk. This disk I chose is just plain XFS disk, no boot entry or anything. Also, most VPS will give you VNC which will make our task easier as we don’t enforce our boot drive to choose another disk by default (trust me, it’s complicated)
Last words before I begin — as usual: Read and learn as your risk, bcoz any data loss or any monetary damage is your fault, I’ll not be responsible. If data is important, backup it before we begin.
Copy the root partition
First, I have a second disk mounted on /mnt
> mount /dev/sdb1 /mnt
> lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 488M 0 part /boot
└─sda2 8:2 0 49.5G 0 part /
sdb 8:16 0 80G 0 disk
└─sdb1 8:17 0 80G 0 part /mnt
sr0 11:0 1 1024M 0 rom
I copied all of my root disk to there
rsync -avxHAX --progress / /mnt/
We gonna note the UUIDs here
> blkid
/dev/sda2: UUID="e0b6a590-a595-4f11-b771-82d13a3e07e9" TYPE="ext4" PARTUUID="b0036ea3-02"
/dev/sda1: UUID="99057368-5f18-4aa3-a65e-91fdef205027" TYPE="ext4" PARTUUID="b0036ea3-01"
/dev/sdb1: UUID="f9c78304-defa-468e-9caf-7a2567b3ad09" TYPE="xfs" PARTUUID="db8255b7-5140-4b9e-94d7-afc7481f57a8"
Then I need to change the /mnt/etc/fstab , checking also with the partition type
-UUID=e0b6a590-a595-4f11-b771-82d13a3e07e9 / ext4 relatime,grpquota,quota,usrquota,rw 0 1
+UUID=f9c78304-defa-468e-9caf-7a2567b3ad09 / xfs relatime,grpquota,quota,usrquota,rw 0 1
Configure boot partition
I need to check if I’m booting under UEFI or BIOS
> [ -d /sys/firmware/efi ] && echo "UEFI Boot Detected" || echo "Legacy BIOS Boot Detected"
Legacy BIOS Boot Detected
OK I’m using old BIOS so I’m gonna using method below, please be aware if your VPS is UEFI please stop reading and ask ChatGPT what equivalent commands to run grub2-mkconfig for systems with UEFI.
The next thing that I need to do is reload grub to allow detecting other disk boot and forcefully add xfs and ext4 drivers (because our current initramfs only load ext4) into the initramfs using dracut.
grub2-mkconfig -o /boot/grub2/grub.cfg
dracut --force --add-drivers "xfs ext4" --regenerate-all
You can check the new initramfs content by lsinitrd /boot/initramfs-$(uname -r).img .
Then open VNC to reboot, switch to other disk. If there’s multiple option try one by one until you found the one that successfully boots (bcos the other options may using other initramfs with old kernel/not loaded by our last dracut).

Now connect to SSH and confirm if we have switched root partition.
> lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 488M 0 part /boot
└─sda2 8:2 0 49.5G 0 part
sdb 8:16 0 80G 0 disk
└─sdb1 8:17 0 80G 0 part /
sr0 11:0 1 1024M 0 rom
Now we mount the old root partition, wipe it, and clone the data back
mkfs.xfs /dev/sda2 -f
mount /dev/sda2 /mnt
rsync -avxHAX --progress / /mnt/
Chroot to the disk and get the blkid
for dir in boot proc sys dev run; do mount --bind /$dir /mnt/$dir; done
chroot /mnt
blkid
Continue editing the /etc/fstab (still in the chroot!) with the new UUID coming from the disk blkid
-UUID=f9c78304-defa-468e-9caf-7a2567b3ad09 / xfs relatime,grpquota,quota,usrquota,rw 0 1
+UUID=054536e0-bf74-4af6-ac74-51d61dc409d1 / xfs relatime,grpquota,quota,usrquota,rw 0 1
Now, still in chroot, update grub and (if you’re using rhel where /boot/loader/entries exists) update loader entries
grub2-mkconfig -o /boot/grub2/grub.cfg
grubby --update-kernel=ALL --remove-args="root"
grubby --update-kernel=ALL --args="root=UUID=054536e0-bf74-4af6-ac74-51d61dc409d1"
# while I'm here I need to turn on quotas too
grubby --update-kernel=ALL --args="rootflags=usrquota,grpquota"
Exit chroot and reboot, and now you should find….
> findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sda2 xfs rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,usrquota,grpquota

