BTRFS copy LXC containers between subvolumes without consuming free space

I have one snapshot of TOS 3.11.16 with several LXC containers and another snapshot of TOS 5.0 HBT and now I want to copy /srv/lxc folder from TOS 3.11.16 to TOS 5.0 without create of duplacite copy and consuming duplicate space. Is it somehow possible to make a copy of folder from one subvolume to another without consuming same amount of space twice ?

On PC I’m using cp --reflink=auto (or =always if you want it to fail in case it can’t do a shallow CoW copy). I’m not 100% sure the command will do it between “two mounted snapshots”, as there’s a chance it will be considered a different filesystem, but it sounds easy enough to try out. BTW, busybox surely doesn’t support the option, but I hope coreutils-cp package does.

unfortunatelly --reflink is not available on busybox openwrt of turris :frowning:

Thought there will be full version of shadow-cp but it is not

Let me be more specific then.

root@turris:~# cat /etc/turris-version 

root@turris:~# opkg install coreutils-cp
Installing coreutils-cp (8.29-2) to root...

root@turris:~# cp --help | grep reflink
      --reflink[=WHEN]         control clone/CoW copies. See below
When --reflink[=always] is specified, perform a lightweight copy, where the
fails, or if --reflink=auto is specified, fall back to a standard copy.

Good idea with coreutils but not, not working between snapshots :frowning:

cp: failed to clone ‘/mnt/snapshot-@36/srv/lxc/pihole/rootfs/./usr/share/doc/libkeyutils1/changelog.Debian.gz’ from ‘././usr/share/doc/libkeyutils1/changelog.Debian.gz’: Cross-device link

1 Like

This seems to be expected - crossing mountpoint subvolume boundary is not supported, according to this thread

That post actually seems to offer a way that should work, if I read it right.

That would be my take as well

You can however cross subvolume boundaries within the same mountpoint.

Well okay, but I am not that experienced with BTRFS and I use schnapps mount X and schnapps mount Y and the result is mount point /mnt/snapshot-@X/ and /mnt/snapshot-@Y/ which are two different mount points so how can I bind them together ? It would really save me 20GB on SDHC card in turris for debian LXC container that I would have to make second copy otherwise as I have one container for TOS 3.11.16 and another one for TOS 5.0.0

Well, in that single post it’s written. I’ve never done it, so lemme try myself:

root@turris:/# mkdir /tmp/mnt-test
root@turris:/# mount -o subvolid=0 /dev/mmcblk0p1 /tmp/mnt-test/
root@turris:/# ls /tmp/mnt-test/      @13         @15         @17         @2          @21         @24         @26         @4          boot.scr
root@turris:/# ls /tmp/mnt-test/@24
bin       boot      boot.scr  dev       etc       lib       mnt       overlay   proc      rom       root      sbin      srv       sys       tmp       usr       var       www
1 Like

Thanks a lot !!

cd /tmp/mnt-test/@38/srv/lxc/pihole# cp -r --reflink=always ./rootfs/. /tmp/mnt-test/@/srv/lxc/pihole/rootfs/

Did the trick ! Now I can use all LXC containers in any TOS 5.0.0 snapshot with HBD, HBL, HBK, HBT together with TOS 3.11.16 on on 64GB SDHC card. It would be impossible otherwise.
What a great feature of BTRFS filesystem I will now use cp -r --reflink=always when needed.

I’ve been using this for years:

alias cp='cp --reflink=auto'

because this was not default (I think; not sure how it’s now).

1 Like