Desejo testar automaticamente se um software reage conforme o esperado, se um arquivo essencial do SQLite DB não for lido (causando um erro de E / S). Exatamente isso aconteceu alguns dias atrás em um cliente. Nós o corrigimos manualmente, mas agora quero criar um código automático para corrigi-lo e preciso acessar um arquivo quebrado para testá-lo.
Como tudo no Unix é um arquivo, suspeitei que possa haver um arquivo especial que sempre cause erros de E / S quando alguém tentar lê-lo (por exemplo, em / dev).
Alguns arquivos semelhantes (imo) seriam:
/dev/full
que sempre diz "Não resta espaço no dispositivo" se você tentar escrevê-lo/dev/null
e/dev/zero
então eu assumi que só precisa haver um arquivo assim (mas ainda não o encontrei).
Alguém conhece um arquivo ou outro método para obter o resultado desejado (uma imagem de partição com defeito intencional, um invólucro em torno de open () usando LD_PRELOAD, ...)?
Qual é a melhor maneira de ir aqui?
Respostas:
Você pode usar
dmsetup
para criar um dispositivo mapeador de dispositivos usando os destinoserror
ouflakey
para simular falhas.Onde 123 é o comprimento do dispositivo, em setores e / dev / loop0 é o dispositivo original no qual você deseja simular erros. Por erro, você não precisa dos argumentos subsequentes, pois sempre retorna um erro.
fonte
dmsetup table test
. Você pode até escrever parafoo bar
tráserror
; simplesmente não se importa (e, portanto, deve ser excluído).Já existe um ótimo conjunto de respostas para isso no Stack Overflow e Server Fault, mas algumas técnicas estavam faltando. Para facilitar a vida, aqui está uma lista dos mecanismos de injeção de falha de E / S do dispositivo de bloco VM / Linux / sistema de arquivos Linux / biblioteca de espaço de usuário Linux:
--layout
opção da página de manual do mdadm para saber como configurá-lo (bits do espaço de usuário do kernel e do mdadm).LD_PRELOAD
).FAIL_MAKE_REQUEST=y
).BLK_DEV_NULL_BLK_FAULT_INJECTION=y
).delay
ouerror
e, em seguida, conecte um dispositivo de bloco a ele vianbd-client
(kernel + bits de espaço de usuário NBD, kernel> = 4.18 criado com suporte a NBD, nbdclient> = 3.18 e nbdkit> = 1.8.1 recomendado - veja o vídeo de demonstração do NBDKit em torno da marca de 20 minutos).Fato bônus: o SQLite possui um driver VFS para simular erros, para obter uma boa cobertura de teste.
Palavras-chave:
fonte
Você deseja um mecanismo de injeção de falha para E / S.
No Linux, aqui está um método que não requer nenhuma configuração anterior e gera um erro incomum (não EIO "Erro de entrada / saída", mas ESRCH "Não existe esse processo"):
onde 1234 é o PID de um processo em execução como o mesmo usuário que o processo que você está testando, mas não o processo em si. Créditos a rubasov por pensar em
/proc/$pid/mem
.Se você usar o PID do próprio processo, obterá a EIO, mas apenas se estiver lendo de uma área que não está mapeada na memória do processo. A primeira página nunca é mapeada; portanto, tudo bem se você ler o arquivo sequencialmente, mas não for adequado para um processo de banco de dados que procura diretamente no meio do arquivo.
Com um pouco mais de configuração como raiz, você pode aproveitar o mapeador de dispositivos para criar arquivos com setores válidos e setores defeituosos.
Outra abordagem seria implementar um pequeno sistema de arquivos FUSE . EIO é o código de erro padrão quando o driver do sistema de arquivos do espaço do usuário faz algo errado, por isso é fácil de obter. As ligações Perl e Python vêm com exemplos para começar; você pode escrever rapidamente um sistema de arquivos que espelha principalmente os arquivos existentes, mas injeta uma EIO em locais cuidadosamente escolhidos. Existe um sistema de arquivos existente: petardfs ( artigo ), eu não sei o quão bem ele funciona imediatamente .
Ainda outro método é um
LD_PRELOAD
invólucro. Um existente é o Libfiu (injeção de falha no espaço do usuário). Ele funciona pré-carregando uma biblioteca que sobrecarrega as chamadas da API POSIX. Você pode escrever diretivas simples ou código C arbitrário para substituir o comportamento normal.fonte
A solução é muito mais fácil se estiver OK usar um arquivo de dispositivo como "arquivo com erros de E / S". Minha proposta é para os casos em que um arquivo regular deve ter esses erros.
Devo admitir que estou um pouco confuso porque não consegui ler setores únicos desse arquivo sem erro (com
dd .. seek=...
). Talvez esse seja um problema de leitura antecipada.fonte
Você pode usar o CharybdeFS criado exatamente para esse tipo de objetivo.
É um sistema de arquivos de fusíveis de passagem como o PetardFS, mas muito mais configurável.
Consulte o livro de receitas do CharybdeFS aqui: http://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/
É avançado o suficiente para testar um banco de dados.
fonte