Как получить Btrfs для проверки контрольной суммы для одного файла?

895
Greendrake

Btrfs предлагает эти команды для проверки целостности данных / контрольных сумм:

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

Однако AFAIK всегда проверяет целые файловые системы; pathаргумент, чтобы определить файловую систему на устройстве, а не файл / каталог в файловой системе.

Теперь у меня есть файловая система Btrfs объемом 3 ТБ. Очистка занимает несколько часов. Иногда мне нужно убедиться, что bitrot еще не затронул только определенный файл / каталог, например, перед использованием установочного образа * .iso или восстановлением резервной копии. Как мне использовать Btrfs для этого - не прибегая к хранению хеш-файлов вручную для каждого файла?

Мне известно, что Btrfs не хранит контрольные суммы для отдельных файлов - он хранит контрольные суммы для блоков данных . В этом случае я ищу команду / инструмент, который идентифицирует все блоки, используемые для хранения определенных файлов / каталогов, и проверяет только эти блоки.

Я где-то читал, что Btrfs якобы проверяет контрольные суммы на чтение . То есть, если файл был бит-гнилой, чтение его не удастся или что-то в этом роде. Это тот случай?

2
У вас регулярно возникают проблемы с повреждением файлов? Это ненормально, я бы заподозрил сначала плохой диск или оперативную память, а потом драйверы файловой системы. Вместо того, чтобы хранить хеши или контрольные суммы в отдельной базе данных для проверки файлов, вы можете хранить файлы в архиве, в котором хранится сама контрольная сумма, и также сэкономить место. Xen2050 6 лет назад 0
@ Xen2050 нет, никаких проблем пока нет, просто хочу получить 100% уверенность. Архивы со встроенными контрольными суммами являются опцией, но я бы хотел использовать Btrfs. Greendrake 6 лет назад 0

1 ответ на вопрос

1
Greendrake

Ответ: просто попробуйте прочитать весь файл . Если он читается не так, как было проверено, будет ошибка ввода / вывода . Так что да, Btrfs действительно проверяет контрольные суммы на чтение!

Чтобы узнать этот ответ, я собрал следующий тест:

  1. Выделите файл размером 1 Гб для использования в качестве блочного устройства для тестирования раздела Btrfs, смонтируйте его как устройство петли и отформатируйте на нем Btrfs;
  2. Создайте фиктивный файл 800 Мб, содержащий известную уникальную последовательность байтов в середине ( token1);
  3. Запишите файл в Btrfs и запишите его sha256 для дальнейшего использования;
  4. Размонтируйте и исправьте файл блочного устройства, чтобы изменить один байт. Для этого мы sed-replace token1с token2;
  5. Смонтируйте снова и попробуйте получить sha256 из файла 800 Мб на Btrfs. См. Ошибка ввода / вывода;
  6. Размонтируйте, исправьте, смонтируйте и убедитесь, что файл 800 Мбайт снова доступен для чтения, и sha256 такой же, как на шаге 3;
  7. Прибыль!

Вот сценарий:

#!/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!" 

Как и ожидалось, замена mkfs.btrfsна создание файловой системы без контрольной суммы (например mkfs.ext4) позволяет считывать поврежденный файл. Конечно, его sha256 отличается от не испорченного.

Похожие вопросы