Estou fazendo a transição de um conjunto de arquivos grande de um sistema de arquivos com alto _PC_LINK_MAX
(número máximo de hardlinks por inode) para um inferior.
Em particular, estou brincando com o Amazon EFS, que tem no máximo 175, conforme ditoaqui.
Então, eu gostaria que a entrada fosse um conjunto de arquivos com contagens de links de até 250 reorganizados, para que os inodes fossem divididos, de modo que o máximo fosse 100 links cada.
Existe uma invocação inteligente de, digamos, hardlink
que possa fazer isso? Ou talvez uma opção rsync -aH
ou talvez cp -a
que possa ajudar?
...caso contrário, alguma pirataria é necessária...
Responder1
A situação é complicada. Imagine que o máximo de links é 5 e você tem 12 arquivos
a01
com a12
todos os links físicos. Você precisa dividir a01..a05
and a06..a10
and a11..a12
, onde a06
e a07
etc ainda estão vinculados, mas não a01
.
Aqui está um script bash rsync
que é executado em um exemplo de diretório de origem ( src=/usr/libexec/git-core/
) no meu sistema que possui 110 links físicos. 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 omuitos linkserros e não usar esta função.
Após o rsync normal inicial (com erros), a lista de arquivos ausentes é criada usando rsync -ni
, extraindo os nomes dos arquivos na função calctodo
para /tmp/todo
.
Há então um loop onde coletamos rsync
os arquivos ausentes, novamente ignorandomuitos linkserros (que você teria se tivesse mais de 2*175
links no diretório original). Os arquivos criados com sucesso são vinculados 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
Você pode precisar revisar isso se tiver nomes de arquivos com " => ", novas linhas e assim por diante.
Observe que você pode encontrar o número máximo de links suportados por um sistema de arquivos clicando em
getconf LINK_MAX /some/directory