¿Causar intencionalmente un error de E / S en Linux?

42

¿Hay alguna forma, con Linux, de hacer que un dispositivo de bloque informe intencionalmente un error de E / S, o posiblemente simule uno para propósitos de prueba?

Dok
fuente
¿Estás simulando una falla de disco? Quizás podría montar un directorio y luego desmontarlo mientras estaba en uso.
Shef
2
Escribiría un pequeño módulo de kernel con el que podría cargar modprobe, comportándose como un dispositivo de bloque, y luego otro pequeño programa que se envía ioctl()'sal controlador para que devuelva el valor que desea.
ott--
La misma pregunta en Stack Overlflow y en Unix y Linux .
Gilles 'SO- deja de ser malvado'
Para seguir el comentario que hizo @Gilles, esto también se solicitó en stackoverflow.com/questions/1361518/… (varias respuestas de inyección de fallas diferentes) y stackoverflow.com/questions/1870696/… (use el mapeador de dispositivos).
Anon

Respuestas:

54

Sí, hay una forma muy plausible de hacer esto con el mapeador de dispositivos.

El mapeador de dispositivos puede recombinar dispositivos de bloque en un nuevo mapeo / orden de su elección. LVM hace esto. También admite otros objetivos, (algunos que son bastante novedosos) como 'flakey' para simular un disco defectuoso y 'error' para simular regiones fallidas del disco.

Se puede construir un dispositivo que deliberadamente tenga agujeros negros de E / S que informará errores de E / S cuando se crucen.

Primero, cree un volumen virtual para usar como objetivo y haga que sea direccionable como un dispositivo de bloque.

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

Entonces, para comenzar, se crea un archivo de 512M que es la base de nuestro dispositivo de bloque virtual en el que perforaremos un 'agujero'. Sin embargo, todavía no existe un agujero. Si fuera mkfs.ext4 /dev/loop0así, obtendría un sistema de archivos perfectamente válido.

Entonces, usemos dmsetup que, usando este dispositivo de bloque, creará un nuevo dispositivo que tiene algunos agujeros. Aquí hay un ejemplo primero

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

Esto creará un dispositivo llamado 'errdev0' (generalmente en / dev / mapper). Cuando escriba dmsetup create errdev0, esperará la entrada estándar y finalizará cuando se ingrese ^ D.

En el ejemplo anterior, hemos realizado un agujero de 5 sectores (2.5kb) en los sectores 261144 del dispositivo de bucle. Luego continuamos a través del dispositivo de bucle como de costumbre.

Este script intentará generar una tabla que colocará agujeros en ubicaciones aleatorias aproximadamente distribuidas alrededor de 16Mb (aunque es bastante aleatorio).

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

El script asume que también ha creado un dispositivo de 512Mb y que su dispositivo de bloque virtual está encendido /dev/loop0.

Puede simplemente enviar estos datos a un archivo de texto como una tabla y canalizarlos dmsetup create errdev0.

Una vez que haya creado el dispositivo, puede comenzar a usarlo como un dispositivo de bloque normal, primero formateándolo y luego colocando archivos en él. En algún momento, deberías encontrarte con algunos problemas de E / S en los que golpeas sectores que realmente son agujeros de E / S en el dispositivo virtual.

Una vez que haya terminado de usar dmsetup remove errdev0para eliminar el dispositivo.

Si desea que sea más probable que obtenga un error de E / S, puede agregar agujeros con más frecuencia o cambiar el tamaño de los agujeros que cree. Tenga en cuenta que colocar errores en ciertas secciones puede causar problemas desde el primer momento, es decir, a 32mb en un dispositivo que no puede escribir un superbloque que ext normalmente intenta hacer, por lo que el formato no funcionará.

Para mayor diversión, puede hacerlo en losetupese momento mkfs.ext4 /dev/loop0y llenarlo con datos. Una vez que tenga un buen sistema de archivos en funcionamiento, simplemente desmonte el sistema de archivos y agregue algunos agujeros usando dmsetup y vuelva a montar eso.

Matthew Ife
fuente
66
No sabía que podías hacer esto. Muy genial.
15

Para verificar la solidez del programa en caso de que su salida falle, puede usar el pseudodispositivo /dev/full, que siempre devuelve "ENOSPACE" cuando se escribe en él.

$ 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
fuente
7

Depende de lo que quieras probar. Usando una LD_PRELOADbiblioteca ed, puedes engañar a las aplicaciones para que piensen cosas como 'todas las escrituras fallan con ENOSPCo EIO' por ejemplo.

Dennis Kaarsemaker
fuente
1

Tal vez podría cambiar la tabla de particiones y hacer que la partición sea más grande de lo que realmente es. Eso probablemente causaría un error de E / S. O si sus discos son conectables en caliente, simplemente puede sacar uno.

Jure1873
fuente