Como testar pendrive e cartão SD no Linux

Uma situação extremamente chata é comprar um pendrive ou cartão SD falsificado.

Você coloca arquivos nele e, ao ler os dados de volta, estes estão corrompidos.

Comprei 4 pendrives de 16 GB e, para evitar essa situação inconveniente, quero testar se eles realmente possuem esse tamanho ou se são falsificados.

Para esses testes, geralmente crio um arquivo grande com dados aleatórios (de 128 MB até 1 GB) e copio ele várias vezes para dentro do pendrive e em seguida verifico se a checksum de cada um dos arquivos bate com a original.

Como testar pendrive e cartão SD no Linux

Testando 4 pendrives de uma vez com ZFS

Só que como dessa vez eu tenho 4 pendrives para testar, optei por fazer um pouco diferente.

Para este teste resolvi usar o sistema de arquivos ZFS.

O ZFS automaticamente guarda checksums de todos os arquivos armazenados e, ao lê-los valida essas checksums. Além disso, há um comando que realiza a verificação de todos os dados gravados.

Então, testar usando o ZFS me poupa o trabalho de manualmente criar checksums e de manualmente verificá-las. Basta gravar arquivos até encher os pendrives e verificar os dados.

Muito cuidado: é possível corromper o seu disco principal com os comandos utilizados.

Instalando as dependências

Realizei o teste no Ubuntu Linux 22.04.

Acredito que a única dependência sejam os utilitários do ZFS.

sudo apt install zfsutils-linux

Formatando

Primeiro listamos os discos.

$ ls -1rt /dev/sd*
> /dev/sda
> /dev/sdb
> /dev/sdc
> /dev/sdd
> /dev/sde

Para descobrir quais dos discos são os pendrives listamos os discos com o programa parted, filtrando os dados de interesse com o comando grep.

$ sudo parted -l | grep '/dev/sd'
> Disk /dev/sda: 1000GB
> Disk /dev/sdb: 15,7GB
> Disk /dev/sdc: 15,7GB
> Disk /dev/sdd: 15,7GB
> Disk /dev/sde: 15,7GB

Dica: Fique atento a qual é o seu disco principal. No meu caso é /dev/sda.

Vamos usar o ZFS para criar uma ZPOOL (conjunto de discos). Criamos uma ZPOOL chamada "teste" com os 4 pendrives em stripes (listras?).

$ sudo zpool create teste sdb sdc sdd sde

Dica: Não adicione o seu disco principal na ZPOOL.

Os pendrives já estavam formatados com FAT, então o ZFS se negou a criar a ZPOOL, o que causaria a perda de dados. Bastou adicionar -f no comando para forçar a criação, pois não tenho nada gravado neles.

Para melhorar um pouco a performance do teste configuramos as seguintes opções:

$ sudo zpool trim teste --wait
$ sudo zfs set atime=off teste
$ sudo zfs set sync=disabled teste
$ sudo zfs set compression=off teste

Sobre as opções habilitadas

Executar um "trim" no sistema de arquivos avisa o pendrive de todo o espaço livre, permitindo utilizá-lo de forma mais efetiva. Esse passo vai ser repetido no fim do teste. É possível que a operação de trim não seja suportada pelo pendrive ou cartão SD.

Além do trim, a única opção que recomendo usar na prática com ZFS é atime=off. Isso evita atualizar a data de acesso a cada leitura. Não tem porque transformar uma leitura em uma leitura-e-escrita, por isso o uso dessa opção é comum e recomendada.

As outras duas opções é só pra deixar o teste mais rápido e podem ter consequências indesejadas.

A opção sync=disabled, do ponto de vista da aplicação, pode afetar seriamente a consistência dos dados gravados. A maioria das aplicações, precisam que todas as gravações sejam síncronas: "só quero continuar quando os dados estiverem efetivamente gravados no disco." Essa opção mente para estas aplicações, tornando todas as gravações assíncronas.

Na prática, recomendo usar sync=standard, que deixa a aplicação escolher entre síncrono e assíncrono.

Já a opção compression=off serve para não comprimir os dados no disco.

Sim, outra vantagem do ZFS é que ele pode comprimir dados, automaticamente economizando o precioso espaço do disco. Porém, neste teste, compactar seria contra-produtivo porque queremos preencher o disco completamente e então varrê-lo em busca de erros.

Na prática, recomendo usar sync=lz4, que compacta muito bem as sequências de zero, que são muito comuns, e arquivos de texto.

Gravando

Uma coisa muito legal do ZFS é que ele monta tudo automaticamente. Como acabamos de criar uma ZPOOL, é óbvio que vamos utilizá-la e por isso ela já é montada pelo próprio ZFS.

Então basta logar como root (usando sudo), entrar na pasta do ZPOOL e começar a escrever arquivos.

$ sudo -i
$ cd /teste

Os arquivos que vamos escrever são arquivos aleatórios (lidos de /dev/urandom). Criamos uma variável COUNT, que conta o número de arquivos criados e, dentro de um laço while criamos arquivos de 128 MB utilizando o comando dd. Caso o comando dd falhe (ex: por falta de espaço em disco) o comando break pára o laço e aguardamos o sistema operacional sincronizar com o comando sync. Por fim, também já iniciamos o scrub (varredura) nos discos.

# Execute como root
COUNT=0
while :; do
    dd if=/dev/urandom of=file-$COUNT.bin bs=1M count=128 || break
    COUNT="$(($COUNT + 1))"
done
sync
zpool scrub teste

Para ver o andamento da gravação podemos usar os comandos abaixo. Eu prefiro o penúltimo.

$ ls -lh /teste
$ zfs list teste
$ zpool iostat teste 5
$ zpool iostat teste 5 -v

Verificando

Finalizada a gravação, o scrub (varredura) nos discos foi iniciado e o ZFS vai ler todos os dados, de todos os pendrives, e vai validar esses dados com as checksums.

No fim da gravação, logo após o comando sync já iniciamos o scrub, que pode ser iniciado novamente com o comando abaixo.

$ sudo zpool scrub teste

Podemos ver o andamento do scrub no status da ZPOOL.

$ zpool status teste
> ...
>   scan: scrub in progress since ...
>     14.0G scanned at 182M/s, 720M issued at 9.12M/s, 14.0G total
>     0B repaired, 5.01% done, no estimated completion time
> ...

Quando o scrub finalizar vemos o resultado também no status da ZPOOL.

$ zpool status teste
> ...
>   scan: scrub repaired 0B in 00:27:31 with 0 errors on ...
> ...
>     NAME      STATE     READ WRITE CKSUM
>     teste     ONLINE       0     0     0
>       sdb     ONLINE       0     0     0
>       sdc     ONLINE       0     0     0
>       sdd     ONLINE       0     0     0
>       sde     ONLINE       0     0     0
> ...

Ótimas notícias: Nenhum erro!

Limpando e exportando

Agora vamos apagar todos os arquivos e aplicar um "trim" no sistema de arquivos, instruindo ao pendrive que o espaço livre pode ser reutilizado, melhorando a longevidade do pendrive.

$ sudo rm -f /teste/file-*.bin
$ sudo zpool trim teste --wait

Estando tudo finalizado, podemos exportar (ejetar) a ZPOOL para podermos formatar os pendrives e usá-los normalmente.

$ sudo zpool export teste

Conclusão

Em 3 horas os 4 pendrives estavam testados e pude aproveitar boa parte do tempo para escrever este post.

Tamanha a conveniência, acredito que será meu novo método de testes de pendrives e cartões SD.