Wie bekomme ich eine Btrfs-Prüfsumme für eine Datei?

976
Greendrake

Btrfs bietet folgende Befehle zur Überprüfung der Datenintegrität / Prüfsummen:

btrfs scrub start <path>|<device> btrfs check --check-data-csum 

AFAIK überprüft jedoch immer ganze Dateisysteme; Das pathArgument ist, ein Dateisystem auf einem Gerät zu identifizieren, nicht Datei / Verzeichnis innerhalb des Dateisystems.

Jetzt habe ich ein 3TB Btrfs-Dateisystem. Das Schrubben dauert Stunden. Manchmal muss ich sicherstellen, dass nur bestimmte Dateien / Verzeichnisse noch nicht von bitrot betroffen sind - zum Beispiel, bevor Sie ein * .iso-Installationsimage verwenden oder ein Backup wiederherstellen. Wie verwende ich Btrfs dafür - ohne auf manuelle Hash-Dateien für jede Datei zurückzugreifen?

Mir ist bekannt, dass Btrfs keine Prüfsummen für einzelne Dateien speichert, sondern Prüfsummen für Datenblöcke . In diesem Fall suche ich nach einem Befehl / Werkzeug, das alle für das Speichern bestimmter Dateien / Verzeichnisse verwendeten Blöcke identifiziert und nur diese Blöcke überprüft.

Ich habe irgendwo gelesen, dass Btrfs angeblich Prüfsummen beim Lesen überprüft . Das heißt, wenn eine Datei etwas verrottet ist, schlägt das Lesen fehl oder so ähnlich. Ist das der Fall?

2
Haben Sie regelmäßig ein Problem damit, dass Dateien beschädigt werden? Das ist nicht normal. Ich habe den Verdacht, dass zuerst ein fehlerhaftes Laufwerk oder ein fehlerhafter RAM-Speicherplatz vorhanden ist. Anstatt Hashes oder Prüfsummen in einer separaten Datenbank zu speichern, um Dateien zu überprüfen, können Sie Dateien in einem Archiv aufbewahren, das eine Prüfsumme selbst speichert, und würde auch etwas Platz sparen. Xen2050 vor 6 Jahren 0
@ Xen2050 nein, bisher keine Probleme, will nur 100% iges Vertrauen bekommen. Archive mit integrierten Prüfsummen sind eine Option, aber ich möchte Btrfs einsetzen. Greendrake vor 6 Jahren 0

1 Antwort auf die Frage

1
Greendrake

Die Antwort lautet: Versuchen Sie einfach , die gesamte Datei zu lesen . Wenn es anders abläuft als bei der Prüfsumme, liegt ein Eingabe- / Ausgabefehler vor . Also ja, Btrfs prüft tatsächlich Prüfsummen beim Lesen!

Um diese Antwort herauszufinden, habe ich den folgenden Test zusammengestellt:

  1. Weisen Sie eine 1-GB-Datei zu, die als Blockgerät zum Testen der Btrfs-Partition verwendet werden soll, hängen Sie sie als Schleifengerät an und formatieren Sie Btrfs darauf.
  2. Erstellen Sie eine Dummy-Datei mit 800 MB, die eine bekannte eindeutige Folge von Bytes in der Mitte ( token1) enthält.
  3. Schreiben Sie die Datei in die Btrfs und notieren Sie ihre sha256 für spätere Referenz.
  4. Hängen Sie die Blockgerätedatei auf und patchen Sie sie so, dass ein Byte geändert wird. Dafür sedersetzen wir token1mit token2;
  5. Stellen Sie erneut ein und versuchen Sie, sha256 der 800-MB-Datei auf den Btrfs abzurufen. Siehe Eingabe- / Ausgabefehler.
  6. Hängen Sie die Bereitstellung ab, patchen Sie zurück, mounten Sie und stellen Sie sicher, dass die 800-MB-Datei wieder lesbar ist und sha256 wie in Schritt 3 ist.
  7. Profitieren!

Hier ist das Skript:

#!/bin/bash f="btrfstestblockdevicefile" ft="btrfstestfile" loop="/dev/loop0" mount_dir="btrfstestdir" size="1g" token1="36bbf48aa6645646fbaa7f25b64224fb3399ad40bc706c79bb8276096e3c9e8f" token2="36bbf48aa6645646fbaa7f25b64224fb4399ad40bc706c79bb8276096e3c9e8f"  f_mount() { echo "Mounting..." && \ sudo losetup $loop $f && \ if ! [[ -z $1 ]] ; then sudo mkfs.btrfs -q $loop fi mkdir $mount_dir && \ sudo mount $loop $mount_dir }  f_umount() { echo "Unmounting..." && \ sudo umount $loop && \ sudo rmdir $mount_dir && \ sudo losetup -d $loop }  echo "Allocating file for test block device..." && \ fallocate -l $size $f && \ f_mount 1 && \ echo "Generating test file..." && \ dd if=/dev/urandom of="$1" bs=1M count=400 status=none && \ echo $token1 > "$2" && \ dd if=/dev/urandom of="$3" bs=1M count=400 status=none && \ sudo sh -c "cat $1 $2 $3 > $/$" && \ rm "$1" "$2" "$3" && \ echo "Calculating original hash of the file..." && \ sha256sum "$/$" && \ f_umount && \ echo "Patching the file in the block device file..." && \ sed -i "s/$/$/g" $f && sync && \ f_mount && \ echo "Trying to read the file..." && \ sha256sum "$/$" echo "OK, unmount, patch back and try again..." && \ f_umount && \ sed -i "s/$/$/g" $f && sync && \ f_mount && \ sha256sum "$/$" && \ echo "Yay, Btrfs rules! Cleaning up..." && \ f_umount && \ rm $f && \ echo "All clear!" 

Wie zu erwarten, ermöglicht das Ersetzen mkfs.btrfsdurch ein Nicht-Prüfsummen-Dateisystem (z. B. mkfs.ext4) das Lesen der beschädigten Datei. Natürlich unterscheidet sich sein sha256 vom nicht beschädigten.