script útil para reduzir a contagem de hardlinks?

2

Estou fazendo a transição de um grande conjunto de arquivos de um sistema de arquivos com um alto _PC_LINK_MAX (número máximo de hardlinks por inode) para um menor.

Em particular, estou brincando com o Amazon EFS, que tem no máximo 175, como declarado aqui .

Então, eu gostaria de ter a entrada como um conjunto de arquivos com contagens de links de até 250 rejiggered, para que os inodes sejam divididos, de modo que o máximo seja de 100 links cada.

Existe uma invocação inteligente de, digamos, hardlink que pode fazer isso? Ou talvez uma opção para rsync -aH ou talvez cp -a , o que pode ajudar?

... caso contrário, alguma hackeria está em ordem ...

    
por djsadinoff 27.09.2016 / 16:37

1 resposta

1

A situação é complicada. Imagine o máximo de links é 5 e você tem 12 arquivos a01 to a12 todos ligados em conjunto. Você precisa dividir a01..a05 e a06..a10 e a11..a12 , onde a06 e a07 etc ainda são vinculados, mas não a a01 .

Aqui está um script bash usando rsync que é executado em um diretório de origem de exemplo ( src=/usr/libexec/git-core/ ) no meu sistema que possui 110 hard-links. Ele simula um número máximo de 50 links ( max ) no diretório de destino realdest pela função sim . Em um caso real, você simplesmente ignoraria os erros muitos links e não usaria essa função.

Após o rsync inicial normal (com erros), a lista de arquivos ausentes é criada usando rsync -ni , extraindo os nomes dos arquivos na função calctodo into /tmp/todo .

Existe então um loop em que rsync dos arquivos ausentes, novamente ignorando muitos links erros (o que você teria se tivesse mais de 2*175 links no diretório original). Os arquivos criados com sucesso são linkados entre si. A nova lista de arquivos ausentes é calculada. Isso é repetido até que não haja mais arquivos.

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

Talvez seja necessário revisar isso se você tiver nomes de arquivo com "= >", novas linhas e assim por diante.

Note que você pode encontrar o número máximo de links suportados por um sistema de arquivos

getconf LINK_MAX /some/directory
    
por 27.09.2016 / 19:00