cloning a system from ext4 to btrfs with snapshots

I’m planning to move a computer to a new hardware. The / partition is ext4 and I’m thinking changing it to btrfs with snapshots. I have done something similar before between other fs like ext3 to reiserfs or reiserfs to ext4 and it was easy, just create the new partition with the new fs and copy the files. I’m going to use rsync to copy the files.
Could this approach work with btrfs?.
I have seen that there is another possible way to do it: create the / partition in the new hardware as ext4 and then convert it to btrfs with btrfs-convert. But it is said id will not work with a root partition… even if it is not mounted?

To use “boot from snapshots” special btrfs subvolume layout is needed. This layout is created during installation; there is no single script or command to do it, there are multiple steps performed by different tools at different points in time.

The following manual procedure may work (at least I assume it worked at the time of writing), but there is no guarantee that default subvolume list has not changed: Creating openSUSE-style btrfs root partition & subvolumes

For simple snapper (without booting from snapshots) layout does not really matter, but it is still better to separate root subvolume and /.snapshots subvolume.

I have seen that there is another possible way to do it: create the / partition in the new hardware as ext4 and then convert it to btrfs with btrfs-convert

btrfs convert does not seem to be used (and tested) often and periodically there are reports on btrfs list about strange post-conversion issues. I would avoid it.

But it is said id will not work with a root partition… even if it is not mounted?

I do not see how root partition differs from non-root partition here. But you also need to reinstall bootloader with correct information about new filesystem (at least if /boot is on btrfs). Although you need to do it anyway.

[QUOTE=fperal;3039019]I’m planning to move a computer to a new hardware. The / partition is ext4 and I’m thinking changing it to btrfs with snapshots. I have done something similar before between other fs like ext3 to reiserfs or reiserfs to ext4 and it was easy, just create the new partition with the new fs and copy the files. I’m going to use rsync to copy the files. Could this approach work with btrfs?.

It work for me.

[QUOTE]I have seen that there is another possible way to do it: create the / partition in the new hardware as ext4 and then convert it to btrfs with btrfs-convert. But it is said id will not work with a root partition… even if it is not mounted?

I tried this once, failed and refrain from doing it again.

Yes, as long as you copy files from one Linux file system type to another Linux file system type. there is no problem.

This is BTW not called “cloning” as I understand this phenomenon. IMHO cloning is a low level byte by byte copy of one piece of mass-storage to another (like you can do with the dd command). Has nothing to do with copying on the file level.

Rsyncing from e.g. an ext4 system partition to a btrfs system partition requires some consideration. Check details of subvolume mounting on target btrfs: Expert Partitioner | Reference | openSUSE Leap 15.5 Don’t mess. Most of the time you will want to exclude /etc/fstab.

I’m using system rescue to rsync the system. I have created the btrfs partition and its subvolumes in the new hardware


[root@sysrescue ~]# mkfs -t btrfs /dev/sda1
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/boot/grub2/x86_64-efi
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/opt
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/srv
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/tmp
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/usr/local
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/var
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/software
[root@sysrescue ~]# btrfs subvolume create /tutatis/root/.snapshots

Then I have mounted the subvolumes


[root@sysrescue ~]# mount /dev/sda1  /tutatis/root
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/boot/grub2/i386-pc /tutatis/root/boot/grub2/i386-pc
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/boot/grub2/x86_64-efi /tutatis/root/boot/grub2/x86_64-efi
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/opt /tutatis/root/opt
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/srv /tutatis/root/srv
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/tmp /tutatis/root/tmp
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/usr/local /tutatis/root/usr/local
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/var /tutatis/root/var
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/software /tutatis/root/software
[root@sysrescue ~]# mount /dev/sda1  -o subvol=/.snapshots /tutatis/root/.snapshots

And I check that all is mounted

I have enabled rsyncd in the target system

[root@sysrescue ~]# cat /etc/rsyncd.conf    
uid = root
gid = root
use chroot = no
max connections = 4
syslog facility = local5
pid file = /run/rsyncd.pid



[root]
path=/tutatis/root
read only=no
host allow=192.168.2.2
[root@sysrescue ~]# 

And I will copy the files using

rsyncd --bwlimit 100000000 -aAxXHu --times --delete / 192.168.2.163::root

In the source filesystem everything (/opt /var etc.) is under /
Will it copy everything in it’s corresponding subvolume, right?

I don’t think so. Volumes should be:


ID 256 gen 390515 top level 5 path @ 
ID 258 gen 392039 top level 256 path @/var 
ID 259 gen 391880 top level 256 path @/usr/local 
ID 261 gen 391478 top level 256 path @/srv 
ID 262 gen 392032 top level 256 path @/root 
ID 263 gen 391642 top level 256 path @/opt 
ID 264 gen 390525 top level 256 path @/boot/grub2/x86_64-efi 
ID 265 gen 390527 top level 256 path @/boot/grub2/i386-pc 
ID 266 gen 392033 top level 256 path @/.snapshots

Create and mount partition:

**3400G:~ #** mount /dev/sdc7 /mnt/                  
**3400G:~ #** btrfs subvolume list /mnt              
**3400G:~ #**

Add subvolumes:

[FONT=monospace]**3400G:~ #** btrfs subvolume create /mnt/@ 
Create subvolume '/mnt/@' 
**3400G:~ #** btrfs subvolume create /mnt/@/var 
Create subvolume '/mnt/@/var' 
[/FONT]...[FONT=monospace]**
3400G:~ #**[/FONT]
**3400G:~ #** btrfs subvolume list /mnt     
ID 256 gen 12 top level 5 path @ 
ID 257 gen 12 top level 256 path @/var 
**3400G:~ #**

Compare to these:

**3400G:~ #** grep UUID=2b54b9ff-84c9-4db2-841b-aff657a64325 /etc/fstab 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /                       btrfs  defaults                      0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /var                    btrfs  subvol=/@/var                 0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /usr/local              btrfs  subvol=/@/usr/local           0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /srv                    btrfs  subvol=/@/srv                 0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /root                   btrfs  subvol=/@/root                0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /opt                    btrfs  subvol=/@/opt                 0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /boot/grub2/x86_64-efi  btrfs  subvol=/@/boot/grub2/x86_64-efi  0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /boot/grub2/i386-pc     btrfs  subvol=/@/boot/grub2/i386-pc  0  0 
**UUID=2b54b9ff-84c9-4db2-841b-aff657a64325**  /.snapshots             btrfs  subvol=/@/.snapshots          0  0 
**3400G:~ #**

See Expert Partitioner | Reference | openSUSE Leap 15.5

You are now ready to rsync individual subvolumes. Watch for cow.

I read the expert partitioner doc, but it talked about partitioning from yast, but as I was not using yast I search and followed this guide. The result is

[root@sysrescue ~]# btrfs subvolume list /tutatis/root
ID 257 gen 8 top level 5 path boot/grub2/i386-pc
ID 258 gen 10 top level 5 path boot/grub2/x86_64-efi
ID 259 gen 11 top level 5 path opt
ID 260 gen 12 top level 5 path srv
ID 261 gen 13 top level 5 path tmp
ID 262 gen 14 top level 5 path usr/local
ID 263 gen 15 top level 5 path var
ID 264 gen 19 top level 5 path software
ID 265 gen 17 top level 5 path .snapshots
[root@sysrescue ~]# 

It seems pretty much like the one you posted but without the @
So I understant that what I have to do is the same I did but instead of

btrfs subvolume create /tutatis/root/something

I should use

btrfs subvolume create /tutatis/root/@/something

Correct?

And the question is, what is @ ?

Your subvolume names are different. Your results may be different. I use openSUSE defaults on all my machines as posted above. I never tried different volume names. I don’t know whether your settings work and whether there are some side effects.

openSUSE Tumbleweed defaults:

**erlangen:~ #** btrfs subvolume list / 
ID 256 gen 67589 top level 5 path @ 
ID 257 gen 155751 top level 256 path @/var 
ID 258 gen 155213 top level 256 path @/usr/local 
ID 259 gen 155018 top level 256 path @/tmp 
ID 260 gen 153967 top level 256 path @/srv 
ID 261 gen 155744 top level 256 path @/root 
ID 262 gen 155010 top level 256 path @/opt 
ID 263 gen 150002 top level 256 path @/boot/grub2/x86_64-efi 
ID 264 gen 119878 top level 256 path @/boot/grub2/i386-pc 
ID 265 gen 155023 top level 256 path @/.snapshots 
**erlangen:~ #**