I try to create a snapshot copy of a directory recursively, but it returns errors for every single file if the filesystem (custom shfs) does not support reflink
copies:
# cp -a --reflink=always /mnt/user/libvirt /mnt/user/libvirt_copy
cp: failed to clone '/mnt/user/libvirt_copy/libvirt/libvirt.img' from '/mnt/user/libvirt/libvirt.img': Operation not supported
cp: failed to clone '/mnt/user/libvirt_copy/libvirt/test.txt' from '/mnt/user/libvirt/test.txt': Operation not supported
...
As it seems to be impossible to stop cp
on the first error (?), which means useless looping through probably thousands of files, I instead like to pre-check if the filesystem supports reflinks.
One idea is to search for a single file and do a testcopy:
if ! find /mnt/user/libvirt -type f -print -quit | xargs -I {} sh -c 'dst_path=$(dirname $(echo {} | sed "s#^/mnt/user/libvirt#/mnt/user/libvirt_copy#")); mkdir -vp $dst_path && cp -a --reflink=always {} "$dst_path"'; then
echo "Error: Filesystem does not support reflink"
exit
fi
But this leaves the dir and an empty file which needs to be cleaned up afterwards:
# find /mnt/user/libvirt_copy/
/mnt/user/libvirt_copy/
/mnt/user/libvirt_copy/libvirt.img
# ls -lah /mnt/user/libvirt_copy/libvirt.img
-rw------- 1 root root 0 Nov 1 08:58 /mnt/user/libvirt_copy/libvirt.img
Isn't there an better way? Or maybe there is a solution to stop cp
on the first error?