Como obter o Btrfs para verificar a soma de verificação de um arquivo?

2

O Btrfs oferece esses comandos para verificar a integridade dos dados / somas de verificação:

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

No entanto, os AFAIK sempre verificam sistemas de arquivos todo ; o argumento path é para identificar um sistema de arquivos em um dispositivo, não um arquivo / diretório dentro do sistema de arquivos.

Agora, eu tenho um sistema de arquivos Btrfs de 3TB. Esfregar leva horas. Às vezes, preciso ter certeza de que apenas determinado arquivo / diretório ainda não foi afetado pelo bitrot - por exemplo, antes de usar uma imagem de instalação * .iso ou restaurar um backup. Como faço para usar o Btrfs para isso - sem voltar a manter arquivos hash manuais por cada arquivo?

Estou ciente de que o Btrfs não armazena somas de verificação para arquivos individuais - armazena checksums para blocos de dados . Nesse caso, o que estou procurando é um comando / ferramenta que identifique todos os blocos usados para armazenar determinados arquivos / diretórios e verifique apenas esses blocos.

Eu li em algum lugar que o Btrfs supostamente verifica checksums em read . Ou seja, se um arquivo tiver sido apodrecido, a leitura falhará ou algo assim. É este o caso?

    
por Greendrake 13.01.2018 / 08:20

1 resposta

1

A resposta é: simplesmente tente ler o arquivo inteiro . Se ele for diferente do que foi verificado, haverá um Erro de entrada / saída . Então, sim, o Btrfs realmente verifica as somas de verificação na leitura!

Para descobrir essa resposta, eu fiz o seguinte teste:

  1. Aloque um arquivo de 1 Gb para ser usado como um dispositivo de bloco para testar a partição Btrfs, monte-o como um dispositivo de loop e formate Btrfs nele;
  2. Crie um arquivo fictício de 800 Mb contendo uma seqüência de bytes única e conhecida no meio ( token1 );
  3. Grave o arquivo no Btrfs e grave seu sha256 para referência posterior;
  4. Desmonte e corrija o arquivo de dispositivo de bloco para que um byte seja alterado. Para isso, sed -replace token1 com token2 ;
  5. Monte novamente e tente obter o sha256 do arquivo de 800 Mb no Btrfs. Veja o erro de entrada / saída;
  6. Desmonte, corrija de volta, monte e veja que o arquivo de 800 Mb é legível novamente e sha256 é o mesmo da etapa 3;
  7. Lucro!

Aqui está o script:

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

Como esperado, a substituição de mkfs.btrfs por um sistema de arquivos sem soma de verificação (por exemplo, mkfs.ext4 ) permite que o arquivo corrompido seja lido. Claro, o seu sha256 é diferente do não corrompido.

    
por 15.01.2018 / 02:14