Я переношу большой набор файлов из файловой системы с высоким значением _PC_LINK_MAX
(максимальное количество жестких ссылок на inode) в файловую систему с более низким значением.
В частности, я имею дело с Amazon EFS, у которого, как указано, максимум 175.здесь.
Поэтому я хотел бы, чтобы входными данными был набор файлов с количеством ссылок до 250, перестроенных так, чтобы иноды были разделены так, чтобы максимум в каждом было 100 ссылок.
Есть ли умный вызов, скажем, hardlink
который может это сделать? Или, может быть, вариант rsync -aH
или, может быть, cp -a
который может помочь?
...в противном случае придется прибегнуть к хакерским уловкам...
решение1
Ситуация сложная. Представьте, что максимальное количество ссылок равно 5, а у вас есть 12 файлов,
a01
которые a12
все жестко связаны друг с другом. Вам нужно разделить a01..a05
и a06..a10
и a11..a12
, где a06
и a07
и т. д. все еще жестко связаны друг с другом, но не a01
.
Вот скрипт bash rsync
, который работает на примере исходного каталога ( src=/usr/libexec/git-core/
) в моей системе, которая имеет 110 жестких ссылок. Он имитирует максимальное количество ссылок 50 ( max
) в целевом каталоге realdest
функцией sim
. В реальном случае вы бы просто проигнорировалислишком много ссылокошибки и не использовать эту функцию.
После первоначальной нормальной rsync (с ошибками) список отсутствующих файлов создается с помощью rsync -ni
, извлекая имена файлов в функции 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