하드링크 수를 줄이는 편리한 스크립트?

하드링크 수를 줄이는 편리한 스크립트?

더 높은(inode당 최대 하드 링크 수) 파일 시스템의 대용량 파일 세트를 _PC_LINK_MAX더 낮은 파일 시스템으로 변환하고 있습니다.

특히 위에서 언급한 것처럼 최대 175개까지 지원하는 Amazon EFS를 사용하고 있습니다.여기.

따라서 입력이 파일당 최대 링크 수가 100이 되도록 inode가 분할되도록 크기가 조정된 최대 250개의 링크가 있는 파일 세트가 되기를 원합니다.

hardlink 이를 수행하는 영리한 호출이 있습니까 ? 아니면 옵션이 있거나 도움이 rsync -aH될까요 cp -a?

...그렇지 않으면 일부 해킹이 필요합니다...

답변1

상황이 까다롭습니다. 최대 링크가 5개이고 a01모두 a12하드 링크된 12개의 파일이 있다고 가정해 보세요. 과 등 이 여전히 서로 하드 연결되어 있는 경우 a01..a05합계를 분할해야 하지만 .a06..a10a11..a12a06a07a01

이것은 110개의 하드 링크가 있는 rsync내 시스템의 예제 소스 디렉터리( )에서 실행되는 bash 스크립트입니다 . src=/usr/libexec/git-core/이 함수를 통해 max대상 디렉터리에서 최대 50개의 link()를 시뮬레이션합니다. 실제 상황에서는 무시할 것입니다.realdestsim링크가 너무 많습니다.오류가 발생하여 해당 기능이 사용되지 않습니다.

rsync -ni초기 일반 rsync(오류 포함) 후에는 파일 이름을 function 으로 추출하여 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

관련 정보