하드링크 수를 줄이는 편리한 스크립트가 있습니까?

하드링크 수를 줄이는 편리한 스크립트가 있습니까?

_PC_LINK_MAX큰 파일 세트를 높은 파일 시스템 (inode당 최대 하드링크 수) 에서 낮은 파일 시스템으로 전환하려고 합니다 .

특히, 명시된 대로 최대 175개인 Amazon EFS를 사용하고 있습니다.여기.

따라서 입력을 최대 250개의 링크 수가 포함된 파일 세트로 만들어서 inode가 분할되어 최대 링크가 각각 100개가 되도록 하고 싶습니다.

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

...그렇지 않으면 일부 해커가 필요한 것입니다...

답변1

상황이 까다롭습니다. 최대 링크가 5개이고 모두 하드 링크된 a01파일 이 12개 있다고 가정해 보세요. and 등 을 a12분리해야 합니다 . 여기서 및 등은 여전히 ​​함께 하드 링크되어 있지만 에서는 그렇지 않습니다 .a01..a05a06..a10a11..a12a06a07a01

다음은 110개의 하드 링크가 있는 내 시스템의 rsync예제 소스 디렉터리( )에서 실행되는 bash 스크립트입니다 . 이 함수는 대상 디렉토리에서 src=/usr/libexec/git-core/최대 50개의 링크( ) 수를 시뮬레이션합니다 . 실제 사례에서는 그냥 무시하면 됩니다.maxrealdestsim링크가 너무 많아오류가 발생하면 이 기능을 사용하지 마세요.

초기 일반 rsync(오류 포함) 후에 누락된 파일 목록은 을 사용하여 생성되고 함수 rsync -ni의 파일 이름을 . calctodo/tmp/todo

rsync그런 다음 누락된 파일을 다시 무시하는 루프가 있습니다.링크가 너무 많아2*175오류( 원래 디렉토리에 링크가 2 개 이상 있을 경우 발생할 수 있는 오류 ). 성공적으로 생성된 파일은 서로 하드링크되어 있습니다. 누락된 파일의 새 목록이 계산됩니다. 더 이상 파일이 없을 때까지 이 과정이 반복됩니다.

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

관련 정보