Intencionalmente causar um erro de E / S no Linux?

42

Existe alguma maneira, com o Linux, de fazer com que um dispositivo de bloco intencionalmente relate um erro de E / S ou simule um para fins de teste?

Dok
fonte
Você está simulando uma falha no disco? Talvez você possa montar um diretório e desmontá-lo enquanto estiver em uso.
quer
2
Eu escreveria um pequeno módulo do kernel com o qual você poderia carregar modprobe, comportando-se como um dispositivo de bloco e, em seguida, outro pequeno programa enviado ioctl()'sao driver para fazer com que ele retornasse o valor desejado.
ott--
A mesma pergunta no Stack Overlflow e no Unix e Linux .
Gilles 'SO- stop be evil'
Para acompanhar o comentário feito por @Gilles, isso também foi solicitado em stackoverflow.com/questions/1361518/… (várias respostas diferentes de injeção de falha) e stackoverflow.com/questions/1870696/… (use o mapeador de dispositivo).
Anon

Respostas:

54

Sim, há uma maneira muito plausível de fazer isso com o mapeador de dispositivos.

O mapeador de dispositivos pode recombinar os dispositivos de bloco para um novo mapeamento / ordem de sua escolha. O LVM faz isso. Ele também suporta outros destinos (alguns que são bastante novos) como 'flakey' para simular um disco com falha e 'erro' para simular regiões com falha no disco.

Pode-se construir um dispositivo que deliberadamente possua trincas de E / S que reportem erros de E / S quando cruzados.

Primeiro, crie algum volume virtual para usar como destino e torne-o endereçável como um dispositivo de bloco.

dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576
losetup /dev/loop0 /var/lib/virtualblock.img

Portanto, para começar, cria um arquivo de 512M que é a base do nosso dispositivo de bloco virtual no qual perfuraremos um 'buraco'. Ainda não existe um buraco. Se você fosse, mkfs.ext4 /dev/loop0obteria um sistema de arquivos perfeitamente válido.

Então, vamos usar o dmsetup que, usando este dispositivo de bloco - criará um novo dispositivo que possui alguns furos. Aqui está um exemplo primeiro

dmsetup create errdev0
0 261144 linear /dev/loop0 0
261144 5 error
261149 787427 linear /dev/loop0 261139

Isso criará um dispositivo chamado 'errdev0' (normalmente em / dev / mapper). Quando você digita, dmsetup create errdev0ele espera stdin e termina com a entrada de ^ D.

No exemplo acima, fizemos um furo de 5 setores (2,5kb) nos setores 261144 do dispositivo de loop. Em seguida, continuamos pelo dispositivo de loop normalmente.

Este script tentará gerar uma tabela para colocar buracos em locais aleatórios aproximadamente espalhados em torno de 16Mb (embora seja bastante aleatório).

#!/bin/bash
start_sector=0
good_sector_size=0

for sector in {0..1048576}; do

    if [[ ${RANDOM} == 0 ]]; then
        echo "${start_sector} ${good_sector_size} linear /dev/loop0 ${start_sector}"
        echo "${sector} 1 error"
        start_sector=$((${sector}+1))
        good_sector_size=0
    else
        good_sector_size=$((${good_sector_size}+1))
    fi
done

echo "${start_sector} $((${good_sector_size}-1)) linear /dev/loop0 ${start_sector}"

O script supõe que você também criou um dispositivo de 512 Mb e que seu dispositivo de bloco virtual está ativado /dev/loop0.

Você pode simplesmente enviar esses dados para um arquivo de texto como uma tabela e inseri-los dmsetup create errdev0.

Depois de criar o dispositivo, você poderá começar a usá-lo como um dispositivo de bloco normal, primeiro formatando-o e depois colocando arquivos nele. Em algum momento, você deve encontrar alguns problemas de E / S nos quais atinge setores que realmente são buracos de E / S no dispositivo virtual.

Depois de terminar, use dmsetup remove errdev0para remover o dispositivo.

Se você deseja aumentar a probabilidade de obter um erro de E / S, pode adicionar orifícios com mais frequência ou alterar o tamanho dos orifícios criados. Observe que colocar erros em determinadas seções provavelmente causará problemas desde o início, ou seja, a 32mb em um dispositivo que você não pode escrever um superbloco que o ext normalmente tenta, portanto o formato não funcionará.

Para maior diversão - você pode realmente apenas losetupentão mkfs.ext4 /dev/loop0e preenchê-lo com dados. Depois de ter um bom sistema de arquivos em funcionamento, desmonte o sistema de arquivos e adicione alguns furos usando o dmsetup e remonte-o!

Matthew Ife
fonte
6
Eu não sabia que você poderia fazer isso. Muito legal.
15

Para verificar a robustez do programa, caso sua saída falhe, você pode usar o pseudodispositivo /dev/full, que sempre retorna "ENOSPACE" quando gravado em.

$ dd if=/dev/zero of=/dev/full
dd: writing to `/dev/full': No space left on device
1+0 records in
0+0 records out
Raúl Salinas-Monteagudo
fonte
7

Depende do que você deseja testar. Usando uma LD_PRELOADbiblioteca ed, você pode induzir os aplicativos a pensar em coisas como 'todas as gravações falham ENOSPCou EIO', por exemplo.

Dennis Kaarsemaker
fonte
7

Você pode fazer isso de muitas maneiras interessantes. Consulte https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt

Mark Wagner
fonte
3
Você poderia destacar as maneiras "interessantes" relevantes que são específicas para solicitações de disco ( fail_make_request)? Também seria ótimo para evitar a podridão do link.
Deer Hunter
1

Talvez você possa alterar a tabela de partições e torná-la maior do que realmente é. Isso provavelmente causaria um erro de E / S. Ou, se seus discos estiverem conectáveis ​​a quente, você pode simplesmente puxá-lo para fora.

Jure1873
fonte