ファイルシステムが参照リンクコピーをサポートしているかどうかを確認するには?

ファイルシステムが参照リンクコピーをサポートしているかどうかを確認するには?

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...

関連情報