Bagaimana cara mendapatkan Btrfs memverifikasi checksum untuk satu file?

4

Btrfs menawarkan perintah ini untuk memverifikasi integritas data / checksum:

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

Namun, AFAIK yang selalu memverifikasi seluruh sistem file; yang pathargumen adalah untuk mengidentifikasi filesystem di perangkat, tidak mengajukan / direktori di dalam filesystem.

Sekarang, saya memiliki sistem file 3TB Btrfs. Menggosoknya membutuhkan waktu berjam-jam. Terkadang saya perlu memastikan bahwa hanya file / direktori tertentu yang belum terpengaruh oleh bitrot - misalnya, sebelum menggunakan gambar instalasi * .iso atau mengembalikan cadangan. Bagaimana cara menggunakan Btrfs untuk ini - tanpa kembali ke menyimpan file hash manual per setiap file?

Saya sadar bahwa Btrfs tidak menyimpan checksum untuk file individual - ia menyimpan checksum untuk blok data . Dalam hal ini yang saya cari adalah perintah / alat yang mengidentifikasi semua blok yang digunakan untuk menyimpan file / direktori tertentu dan memverifikasi hanya blok-blok itu.

Saya membaca di suatu tempat bahwa Btrfs diduga memverifikasi checksum saat dibaca . Artinya, jika file telah sedikit-busuk, membacanya akan gagal atau semacamnya. Apakah ini masalahnya?

Greendrake
sumber
Apakah Anda secara teratur memiliki masalah dengan file menjadi rusak? Itu tidak normal, saya menduga drive atau ram buruk dulu, mungkin driver sistem file yang buruk kedua. Alih-alih menyimpan hashes atau checksum dalam database terpisah untuk memverifikasi file, Anda bisa menyimpan file dalam arsip yang menyimpan checksum itu sendiri, dan akan menghemat ruang juga.
Xen2050
@ Xen2050 tidak, tidak ada masalah sejauh ini, hanya ingin bisa mendapatkan kepercayaan 100%. Arsip dengan checksum bawaan adalah pilihan, tetapi saya ingin menggunakan Btrfs.
Greendrake

Jawaban:

5

Jawabannya adalah: cukup coba baca seluruh file . Jika terbaca berbeda dari apa yang telah checksum, akan ada kesalahan Input / output . Jadi ya, Btrfs memang memverifikasi checksum saat dibaca!

Untuk mengetahui jawaban ini, saya mengumpulkan tes berikut:

  1. Alokasikan file 1 Gb untuk digunakan sebagai perangkat blok untuk menguji partisi Btrfs, pasang sebagai perangkat loop dan format Btrfs di atasnya;
  2. Buat file 800 Mb boneka yang berisi urutan byte unik yang diketahui di tengah ( token1);
  3. Tulis file ke Btrfs dan catat sha256 untuk referensi nanti;
  4. Lepas dan tambal file blok perangkat sehingga satu byte diubah. Untuk ini, kami sedganti token1dengan token2;
  5. Mount lagi dan coba dapatkan sha256 dari file 800 Mb di Btrfs. Lihat Kesalahan input / output;
  6. Lepas, tambal kembali, pasang dan lihat bahwa file 800 Mb dapat dibaca lagi dan sha256 sama seperti pada langkah 3;
  7. Keuntungan!

Ini skripnya:

#!/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="${ft}1" bs=1M count=400 status=none && \
echo $token1 > "${ft}2" && \
dd if=/dev/urandom of="${ft}3" bs=1M count=400 status=none && \
sudo sh -c "cat ${ft}1 ${ft}2 ${ft}3 > ${mount_dir}/${ft}" && \
rm "${ft}1" "${ft}2" "${ft}3" && \
echo "Calculating original hash of the file..." && \
sha256sum "${mount_dir}/${ft}" && \
f_umount && \
echo "Patching the file in the block device file..." && \
sed -i "s/${token1}/${token2}/g" $f && sync && \
f_mount && \
echo "Trying to read the file..." && \
sha256sum "${mount_dir}/${ft}"
echo "OK, unmount, patch back and try again..." && \
f_umount && \
sed -i "s/${token2}/${token1}/g" $f && sync && \
f_mount && \
sha256sum "${mount_dir}/${ft}" && \
echo "Yay, Btrfs rules! Cleaning up..." && \
f_umount && \
rm $f && \
echo "All clear!"

Seperti yang diharapkan, mengganti mkfs.btrfsdengan membuat sistem file non-checksumming (misalnya mkfs.ext4) memungkinkan untuk file yang rusak untuk dibaca. Tentu saja, sha256 nya berbeda dari yang tidak rusak.

Greendrake
sumber