3

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

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

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

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

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

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

1 ответ1

2

Ответ: просто попробуйте прочитать весь файл. Если он читается не так, как было проверено, будет ошибка ввода / вывода. Так что да, 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="${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!"

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .