praktisches Skript zum Reduzieren der Anzahl von Hardlinks?

praktisches Skript zum Reduzieren der Anzahl von Hardlinks?

Ich konvertiere einen großen Dateisatz von einem Dateisystem mit einer hohen _PC_LINK_MAX(maximale Anzahl von Hardlinks pro Inode) auf ein niedrigeres.

Insbesondere spiele ich mit Amazon EFS herum, das wie angegeben ein Maximum von 175 hatHier.

Daher hätte ich als Eingabe gerne einen Satz von Dateien mit Linkzahlen von bis zu 250, die neu angeordnet wurden, sodass die Inodes so aufgeteilt werden, dass das Maximum bei jeweils 100 Links liegt.

Gibt es eine clevere Aufrufmöglichkeit, hardlink die das kann? Oder vielleicht eine Option, rsync -aHdie cp -ahelfen kann?

...ansonsten ist etwas Hackerei angesagt...

Antwort1

Die Situation ist knifflig. Stellen Sie sich vor, die maximale Anzahl an Links beträgt 5 und Sie haben 12 Dateien, a01die alle fest miteinander verknüpft sind. Sie müssen und und a12aufteilen , wobei und usw. immer noch fest miteinander verknüpft sind, aber nicht mit .a01..a05a06..a10a11..a12a06a07a01

Hier ist ein Bash-Skript, rsyncdas in einem Beispiel-Quellverzeichnis ( src=/usr/libexec/git-core/) auf meinem System läuft, das 110 Hardlinks hat. Es simuliert eine maximale Anzahl von 50 Links ( max) im Zielverzeichnis realdestdurch die Funktion sim. In einem realen Fall würden Sie einfach diezu viele LinksFehler und verwenden Sie diese Funktion nicht.

Nach dem anfänglichen normalen rsync (mit Fehlern) wird die Liste der fehlenden Dateien erstellt rsync -ni, indem die Dateinamen in der Funktion calctodoin extrahiert werden /tmp/todo.

Es gibt dann eine Schleife, in der wir rsyncdie fehlenden Dateien wieder ignorierenzu viele LinksFehler (die auftreten würden, wenn Sie mehr als 2*175Links im Originalverzeichnis hätten). Die erfolgreich erstellten Dateien werden untereinander fest verknüpft. Die neue Liste der fehlenden Dateien wird berechnet. Dies wird wiederholt, bis keine Dateien mehr vorhanden sind.

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

Möglicherweise müssen Sie dies überarbeiten, wenn Sie Dateinamen mit „==“, Zeilenumbrüchen usw. haben.


Beachten Sie, dass Sie die maximale Anzahl von Links, die ein Dateisystem unterstützt, ermitteln können, indem Sie

getconf LINK_MAX /some/directory

verwandte Informationen