減少硬連結數量的方便腳本?

減少硬連結數量的方便腳本?

我正在將一個大型檔案集從具有較高_PC_LINK_MAX(每個 inode 的最大硬連結數)的檔案系統轉換為較低的檔案系統。

特別是,我正在搞亂 Amazon EFS,它的最大數量為 175,如所述這裡

因此,我希望輸入是一組連結計數高達 250 個重新調整的文件,以便 inode 得到拆分,從而每個文件的最大連結數為 100 個。

是否有一種巧妙的調用hardlink 可以做到這一點?或者也許有一個選項rsync -aH或可能cp -a有幫助?

....否則,一些黑客行為是有序的...

答案1

情況很棘手。想像一下最大連結是 5 個,並且您有 12 個檔案 a01全部a12硬連結在一起。您需要拆分a01..a05anda06..a10a11..a12,其中a06anda07等仍然硬鏈接在一起,但不是a01

這是一個 bash 腳本,rsync它在我的系統上的範例來源目錄 ( src=/usr/libexec/git-core/) 上運行,該目錄有 110 個硬連結。它透過該函數模擬max目標目錄中最多 50 個 links( ) 。在實際情況下,你會忽略realdestsim連結太多錯誤,並且不使用該功能。

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

相關內容