SLE12SP2 Migrate root from BTRFS to EXT3 (POWER ppc64le edition)

When installing SLE12 using defaults, the root file system is formatted as BTRFS. BTRFS has many nice features, an instant snapshot capability and the ability to rollback changes in system if using the snapper tool.

However, BTRFS is still too early to call the enterprise FS. Let others debug it, and we will transfer our already installed system to the proven EXT3 FS.

NOTE: my demo system runs on PowerKVM, so the disk is displayed as vda, not sda.

Clone root FS to EXT3

First of all, care about enough space to create a new logical volume. Perhaps you already have it. You can reduce the size of BTRFS online, and then reduce its LV. You can add more disk space, increase the size of the second partition (requires a reboot), and then issue a "pvresize" command.

linux-fb2e:~ # pvs
  PV         VG     Fmt  Attr PSize  PFree
  /dev/vda2  system lvm2 a--  19.99g 8.00m
linux-fb2e:~ # pvresize /dev/vda2
  Physical volume "/dev/vda2" changed
  1 physical volume(s) resized / 0 physical volume(s) not resized
linux-fb2e:~ # pvs
  PV         VG     Fmt  Attr PSize  PFree 
  /dev/vda2  system lvm2 a--  29.99g 10.01g

Create a new LV to be the new root FS and format it:

linux-fb2e:~ # lvcreate -L8g  -n slash /dev/system
  Logical volume "slash" created.
linux-fb2e:~ # mkfs.ext3  -j /dev/system/slash

Mount the destination and source filesystems to be copied by rsync. The order of mount is important, otherwise you can get an infinite loop. Then copy files by rsync:

linux-fb2e:~ # mkdir /mnt/{s,d}
linux-fb2e:~ # mount /dev/system/slash /mnt/d
linux-fb2e:~ # mount -o bind / /mnt/s
linux-fb2e:~ # rsync -av /mnt/s/ /mnt/d/

First boot fix to boot into new root FS

Prepare the chroot environment. It is required for rebuild initrd that suits for our new configuration:

linux-fb2e:~ # cd /mnt/d
linux-fb2e:/mnt/d # mount -t sysfs sysfs sys
linux-fb2e:/mnt/d # mount -t proc proc proc
linux-fb2e:/mnt/d # mount -o bind /dev dev
linux-fb2e:/mnt/d # mount -o bind /dev/pts dev/pts
linux-fb2e:/mnt/d # chroot .
linux-fb2e:/ # PS1="Chroot# "

Now, edit the /etc/fstab to remove all BTRFS mounts and replace them with one:

Chroot# vi /etc/fstab
Chroot# cat /etc/fstab
/dev/system/swap     swap                 swap       defaults              0 0
/dev/system/slash       /       ext3    defaults        1 2

Rebuild initrd in chrooted environment:

Chroot# cd /boot
Chroot# mkinitrd
Creating initrd: /boot/initrd-4.4.21-69-default
dracut: *** Creating initramfs image file '/boot/initrd-4.4.21-69-default' done ***

Leave chroot and copy resulting initrd to original /boot with ".new" extention:

Chroot# exit
linux-fb2e:/mnt/d # cp /mnt/d/boot/initrd-4.4.21-69-default /boot/

Edit original /boot/grub2/grub.cfg. Duplicate the first "menuentry" of SLES, keep original entry as is, in copy replace the root= entry and initrd name, like:

### BEGIN /etc/grub.d/10_linux ###
menuentry 'SLES_SAP 12-SP2 NEW'  --class sles_sap --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-dcbb814a-e17c-4173-808b-25e8d45eebbb' {
        set gfxpayload=text
        insmod gzio
        insmod part_msdos
        insmod lvm
        insmod btrfs
        set root='lvmid/2y8FbM-A0z1-4uKh-u45E-HKDX-21n2-KbgjjL/aizFtx-Ulba-QQc2-ubD2-JUd1-jy4P-qDjMT8'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint='lvmid/2y8FbM-A0z1-4uKh-u45E-HKDX-21n2-KbgjjL/aizFtx-Ulba-QQc2-ubD2-JUd1-jy4P-qDjMT8'  dcbb814a-e17c-4173-808b-25e8d45eebbb
          search --no-floppy --fs-uuid --set=root dcbb814a-e17c-4173-808b-25e8d45eebbb
        echo    'Loading Linux 4.4.21-69-default ...'
        linux   /boot/vmlinux-4.4.21-69-default root=/dev/mapper/system-slash  ${extra_cmdline} splash=silent quiet showopts
        echo    'Loading initial ramdisk ...'
        initrd  /boot/

It's time for the first reboot to the new root FS. If something went wrong, you always can use the original grub entry to fix the problems.

Cleanup and fix boot again

At the moment, we booted into the new root FS using the old grub bootloader.

linux-fb2e:~ # df /
Filesystem               1K-blocks    Used Available Use% Mounted on
/dev/mapper/system-slash   8125880 5028516   2677936  66% /

Remove the old BTRFS root FS to help grub installer understand the required configuration. This is a dangerous part, do not miss a single phase:

linux-fb2e:~ # lvs
  LV    VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  root  system -wi-a-----  19.55g                                                    
  slash system -wi-ao----   8.00g                                                    
  swap  system -wi-ao---- 440.00m                                                    
linux-fb2e:~ # lvremove /dev/system/root
Do you really want to remove active logical volume root? [y/n]: y
  Logical volume "root" successfully removed

Now rebuild the /boot/grub2/grub.cfg using automatic tools:

linux-fb2e:~ # grub2-mkconfig > /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinux-4.4.21-69-default
Found initrd image: /boot/initrd-4.4.21-69-default

Finally, install the grub bootloader based on the new configuration. It should be installed in the first partition of the "PPC PReP Boot" type, unlike Intel-based systems. So, the command will be:

linux-fb2e:~ # grub2-install /dev/vda1
Installing for powerpc-ieee1275 platform.
Installation finished. No error reported.

Make a final reboot.

Updated on Sun Nov 19 22:39:33 IST 2017 More documentations here