удобный скрипт для уменьшения количества жестких ссылок?

удобный скрипт для уменьшения количества жестких ссылок?

Я переношу большой набор файлов из файловой системы с высоким значением _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

Связанный контент