ハードリンクの数を減らす便利なスクリプトはありますか?

ハードリンクの数を減らす便利なスクリプトはありますか?

_PC_LINK_MAX大きなファイルセットを、高い(inode あたりのハードリンクの最大数) ファイルシステムから低いファイルシステムに移行しています。

特に、Amazon EFSは最大175個までしか保存できないので、ここ

したがって、入力を、リンク数が最大 250 のファイル セットにして、i ノードが分割され、最大リンク数がそれぞれ 100 になるように調整したいと思います。

hardlink たとえば、これを実行できる の巧妙な呼び出しはありますか? または、 のオプションrsync -aHや がcp -a役立つでしょうか?

...そうでなければ、何らかのハッキングが必要になります...

答え1

状況は複雑です。最大リンク数が 5 で、 が 12 個のファイル すべてa01にハードリンクされているとします。とをa12分割する必要があります。ここで、やなどはハードリンクされていますが、 には分割されません。a01..a05a06..a10a11..a12a06a07a01

これは、110個のハードリンクを持つ私のシステム上のrsyncサンプルソースディレクトリ( )で実行される を使用したbashスクリプトです。関数 によって、宛先ディレクトリの最大50個のリンク( )をシミュレートします。実際のケースでは、src=/usr/libexec/git-core/maxrealdestsimリンクが多すぎるエラーが発生する可能性があるため、この機能は使用しないでください。

rsync -ni最初の通常の rsync (エラーあり) の後、関数 内のファイル名を に抽出し、を使用しcalctodoて不足しているファイルのリストが作成されます/tmp/todo

rsync次に、不足しているファイルを探すループがあり、これも無視されますリンクが多すぎるエラー (元のディレクトリにリンクが複数ある場合に発生します2*175) は発生しません。正常に作成されたファイルは、相互にハードリンクされます。不足しているファイルの新しいリストが計算されます。ファイルがなくなるまで、これが繰り返されます。

src=/usr/libexec/git-core/
realdest=/tmp/realdest
#rm -fr "$realdest"
max=50
sim(){
    find ${1?} -links +$max |
    sed "1,${max}d" |
    xargs --no-run-if-empty rm
}
calctodo(){
    sed -n '/^hf/{ s/[^ ]* //; s/ =>.*//; p }' >/tmp/todo
}

rsync -aHR   "$src" "$realdest"; sim "$realdest"
rsync -niaHR "$src" "$realdest" | calctodo

while  [ -s /tmp/todo ]
do  mv /tmp/todo /tmp/todo.old
    rsync -aHR  --files-from=/tmp/todo.old / "$realdest"; sim "$realdest"
    rsync -niaHR --files-from=/tmp/todo.old / "$realdest" | calctodo
done

ファイル名に「 => 」や改行などが含まれる場合は、これを修正する必要があるかもしれません。


ファイルシステムでサポートされるリンクの最大数は、次の方法で確認できます。

getconf LINK_MAX /some/directory

関連情報