reflink
ディレクトリのスナップショットコピーを繰り返し作成しようとしましたが、ファイルシステム(カスタムshfs)がコピーをサポートしていない場合、各ファイルに対してエラーが返されます。
# 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
...
潜在的に何千ものファイルの無駄なループを意味する最初のエラー(?)で停止することは不可能に見えるので、ファイルcp
システムがリンク参照をサポートしているかどうかを事前に確認するのが大好きです。
1つのアイデアは、単一のファイルを検索してテストコピーを作成することです。
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
ただし、これにより後でクリーンアップする必要があるディレクトリと空のファイルが残ります。
# 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
もっと良い方法はありませんか?それとも、cp
最初のエラーが発生した場合に停止できる解決策がありますか?
答え1
あなたが言及した「カスタムshfs」ファイルシステムが使用されているかどうかはわかりませんが、ディスク上の一般的なファイルシステムの場合は、それに関する情報を取得するために実行できるファイルシステム固有のコマンドが必要です。たとえば、XFSファイルシステムの場合、shスクリプトは次のように参照接続機能をサポートするかどうかをテストできます。
if xfs_info /yourXfsMount | grep reflink=1; then
echo "Filesystem supports reflink"
else
echo>&2 "ERROR: Filesystem does not support reflink"
exit 1
fi
答え2
特定のファイルシステムに依存しない一般的な答えが必要な場合は、単にテストコピーを作成するのがおそらく最善の方法でしょう。このテストでは既存のデータを使用する必要はなく、再接続したいファイルシステムだけを知ることができます。最も簡単な方法は、一意の名前を持つ空のファイルを作成してコピーし、テストに実際のデータを含まずにクリーンアップすることです。たぶん、次のようなものがあります。
filesystem=/yourFilesystem
filename=${filesystem}/reflinktest-$(uuid)
filename2=${filename}-copy
touch ${filename}
cp --reflink=always ${filename} ${filename2}
result=$?
rm -f ${filename} ${filename2}
if [ ${result} -ne 0 ]; then
echo "ERROR: Filesystem ${filesystem} does not support reflink."
exit 1
fi
echo "Reflink supported"
# Proceed with your reflink copying...