我正在將一個大型檔案集從具有較高_PC_LINK_MAX
(每個 inode 的最大硬連結數)的檔案系統轉換為較低的檔案系統。
特別是,我正在搞亂 Amazon EFS,它的最大數量為 175,如所述這裡。
因此,我希望輸入是一組連結計數高達 250 個重新調整的文件,以便 inode 得到拆分,從而每個文件的最大連結數為 100 個。
是否有一種巧妙的調用hardlink
可以做到這一點?或者也許有一個選項rsync -aH
或可能cp -a
有幫助?
....否則,一些黑客行為是有序的...
答案1
情況很棘手。想像一下最大連結是 5 個,並且您有 12 個檔案
a01
全部a12
硬連結在一起。您需要拆分a01..a05
anda06..a10
和a11..a12
,其中a06
anda07
等仍然硬鏈接在一起,但不是a01
。
這是一個 bash 腳本,rsync
它在我的系統上的範例來源目錄 ( src=/usr/libexec/git-core/
) 上運行,該目錄有 110 個硬連結。它透過該函數模擬max
目標目錄中最多 50 個 links( ) 。在實際情況下,你會忽略realdest
sim
連結太多錯誤,並且不使用該功能。
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