Hier ist meine Situation. Ich habe zwei Cold-Storage-Archivvolumes, die (sollten) identische Datensätze enthalten. Diese Volumes enthalten selten aufgerufene Backups. Ich mache mir Sorgen, dass Bitrot irgendwann eines oder beide davon befällt und die darin enthaltenen Daten subtil beschädigt. Ich weiß, dass ich diff -r
die beiden Volumes durchsuchen und Dateien finden kann, die zwischen den beiden geändert oder verschwunden sind, aber ich bekomme keinen hilfreichen Hinweis darauf, welches Volume die „gute“ Kopie hat. Dies sind USB-Festplatten, und sie in etwas wie ZFS zu konvertieren, scheint … mühsam.
Was ich möchte, ist ein Tool, das den Verzeichnisbaum rekursiv durchläuft und eine Manifestdatei schreibt, die den Pfad und den Dateinamen sowie einen Hash des Dateiinhalts enthält. Ich würde dieses Tool unmittelbar nach dem Schreiben der Daten auf jedes Volume ausführen und die resultierende Manifestdatei auf einem Warmspeicher speichern, möglicherweise unter einer Art Revisionskontrolle.
Von dieser Datei aus möchte ich etwas ausführen können, das genau so funktioniert diff -r
– es würde mir sagen, ob Dateien hinzugefügt, entfernt oder ihr Inhalt geändert wurden. Nur dass es nicht ein Volume mit dem anderen vergleicht, sondern ein Volume mit der bekanntermaßen einwandfreien Manifestdatei. Mit dieser Methode sollte ich in der Lage sein, zu sagen, ob die Daten, die ich in den nächsten Monaten/Jahren von der Festplatte lese, mit den Daten identisch sind, die ich ursprünglich darauf gespeichert habe.
Ich würde annehmen, dass so etwas bereits existiert. Ich kann etwas erhalten, das einer Manifestdatei ähnelt, indem ich Folgendes verwende:
find /mnt/my-volume -type f -exec md5sum {} + > manifest.txt
aber bisher habe ich noch keine gute Methode gefunden, diese Datei zu analysieren und jeden Hash rekursiv zu überprüfen. Außerdem, was weniger wichtig ist, erfahre ich dadurch nicht, ob ein leeres Verzeichnis erschienen oder verschwunden ist. (Ich kann mir nicht vorstellen, warum das wichtig sein sollte, aber es wäre schön zu wissen, dass es passiert ist.)
Bin ich damit auf dem richtigen Weg oder gibt es ein geeigneteres Tool, das so etwas kann?
Antwort1
Sie haben Recht, ein solches Tool gibt es bereits. Ich sehe zwar, dass Ihr Beitrag mit „Linux“ getaggt ist, aber vielleicht wäre eine BSD-orientierte Lösung erbaulich.
FreeBSDs Dienstprogramm mtree(8)kann genau das tun, was Sie verlangen.
Vermuten:
$ find .
.
./c
./c/file3
./b
./b/file2
./a
./a/file1
Um ein Manifest dieser Dateihierarchie zu erstellen, einschließlich eines SHA256-Hashes jeder Datei, gehen Sie wie folgt vor:
$ mtree -c -K sha256 > /tmp/manifest.txt
$ cat /tmp/manifest.txt
# user: diego
# machine: myhost.example.com
# tree: /data/home/diego/foo
# date: Wed Mar 28 10:31:17 2018
# .
/set type=file uid=1001 gid=1001 mode=0710 nlink=1 flags=uarch
. type=dir nlink=5 time=1522257963.738221000
# ./a
/set type=file uid=1001 gid=1001 mode=0600 nlink=1 flags=uarch
a type=dir mode=0710 nlink=2 time=1522257932.680802000
file1 size=29 time=1522257932.682389000 \
sha256digest=6b4114c4f12e63c0ca44073de5ca0a2b39fedaceaa533af3dfdc89f00039c973
# ./a
..
# ./b
b type=dir mode=0710 nlink=2 time=1522257937.929131000
file2 size=29 time=1522257937.930666000 \
sha256digest=9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef
# ./b
..
# ./c
c type=dir mode=0710 nlink=2 time=1522257942.064315000
file3 size=29 time=1522257942.065882000 \
sha256digest=bd617f47217ef0605d3aff036778d10bf18cb2f415c45e8e362e2c091df19491
# ./c
..
Anschließend kann die Dateihierarchie anhand des Manifests überprüft werden, indem das Manifest in mtree weitergeleitet wird:
$ mtree < /tmp/manifest.txt || echo fail
Hinzugefügte, gelöschte, umbenannte oder geänderte Dateien führen dazu, dass die Überprüfung fehlschlägt:
$ touch foo
$ mtree < /tmp/manifest.txt || echo fail
.: modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:37:01 2018)
extra: foo
fail
$ rm foo; touch b/file2; mtree < /tmp/manifest.txt || echo fail
.: modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
b/file2:
modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:39:39 2018)
fail
$ mv c/file3 c/FILE3; rm a/file1; date >> b/file2; mtree < /tmp/manifest.txt || echo fail
.: modification time (Wed Mar 28 10:34:56 2018, Wed Mar 28 10:39:39 2018)
c: modification time (Wed Mar 28 10:25:42 2018, Wed Mar 28 10:41:59 2018)
extra: c/FILE3
b/file2:
size (29, 58)
modification time (Wed Mar 28 10:25:37 2018, Wed Mar 28 10:47:31 2018)
sha256digest (0x9f7a0a49475bb6f98e609a4e057f0bc702c5e4706be5bd656a676fd8d15da7ef, 0x569c17bd1a1ca2447fd8167f103531bf3a7b7b4268f0f68b18506e586e7eea94)
a: modification time (Wed Mar 28 10:25:32 2018, Wed Mar 28 10:41:59 2018)
./a/file1 missing
./c/file3 missing
fail
Antwort2
Das Programm ersetzt den vollständigen md5sum -c manifest.txt
Pfad zur gefundenen Datei, einschließlich aller in der Befehlszeile angegebenen Suchorte , d. h. für die Datei wird dasselbe wie für den Befehl ersetzt.manifest.txt
find
{}
find
./a/b/c/d/e
./a/b/c/d/e
find ./a -type f -exec md5sum {} \;
Das mögliche Problem sind absolute Pfade, daher ist der geeignetere „Befehl zur Manifesterstellung“:
cd /mnt/my-volume; find -type f -exec md5sum {} + > manifest.txt
Sie können die Pfade jedoch jederzeit mit sed
mainfest.txt korrigieren.