43 votos

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

¿Existe alguna manera, con Linux, de hacer que un dispositivo de bloque informe a propósito de un error de E/S, o posiblemente simular uno para fines de prueba?

0 votos

¿Está simulando un fallo de disco? Tal vez podrías montar un directorio y luego desmontarlo mientras está en uso.

2 votos

Yo escribiría un pequeño módulo del kernel que podría cargar con modprobe que se comporta como un dispositivo de bloque, y luego otro pequeño programa que envía ioctl()'s al controlador para que devuelva el valor que desea.

0 votos

La misma pregunta sobre Stack Overflow y en Unix y Linux .

54voto

Matthew Ife Puntos 12680

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

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

Uno puede construir un dispositivo que deliberadamente tiene agujeros negros de IO en él que informará de los errores de IO cuando se cruzan.

En primer lugar, cree algún volumen virtual para utilizarlo como destino y hágalo 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

Así que, para empezar, esto crea un archivo de 512M que es la base de nuestro dispositivo de bloque virtual al que le haremos un "agujero". Sin embargo, todavía no existe ningún agujero. Si usted fuera a mkfs.ext4 /dev/loop0 obtendrías un sistema de archivos perfectamente válido.

Por lo tanto, vamos a utilizar dmsetup que, utilizando este dispositivo de bloque -- creará un nuevo dispositivo que tiene algunos agujeros en él. 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' (normalmente en /dev/mapper). Cuando escriba dmsetup create errdev0 esperará por stdin y terminará cuando se introduzca ^D.

En el ejemplo anterior, hemos hecho un agujero de 5 sectores (2,5kb) en los sectores 261144 del dispositivo de bucle. A continuación, continuamos a través del dispositivo de bucle de forma normal.

Este scriptintentará generar una tabla que colocará agujeros en lugares aleatorios aproximadamente repartidos 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 has creado un dispositivo de 512Mb y que tu dispositivo de bloque virtual está en /dev/loop0 .

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

Una vez que hayas creado el dispositivo, puedes empezar a utilizarlo como un dispositivo de bloque normal, primero formateándolo y luego colocando archivos en él. En algún momento te encontrarás con algunos problemas de E/S en los que te encuentras con sectores que en realidad son agujeros de E/S en el dispositivo virtual.

Una vez que haya terminado de utilizar dmsetup remove errdev0 para retirar el dispositivo.

Si quieres que sea más probable que se produzca un error IO puedes añadir agujeros con más frecuencia o cambiar el tamaño de los agujeros que crees. Tenga en cuenta que poner errores en ciertas secciones es probable que cause problemas desde el principio, es decir, en 32mb en un dispositivo que no puede escribir un superbloque que normalmente intenta hacer, por lo que el formato no funciona.

Para divertirse aún más, se puede losetup entonces mkfs.ext4 /dev/loop0 y llenarlo de datos. Una vez que tengas un buen sistema de archivos que funcione, simplemente desmonta el sistema de archivos y añade algunos agujeros usando dmsetup y vuelve a montarlo.

6 votos

No sabía que se podía hacer esto. Bastante bien.

16voto

Benjie Puntos 3416

Para comprobar la robustez del programa en caso de que su salida falle, puede utilizar 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

0 votos

Hola, he probado tus sugerencias y ha funcionado, pero sólo muestra el mensaje de error en cmd y no en el archivo de registro dmesg. ¿Existe alguna forma de enviar estos mensajes de error al archivo de registro dmesg o de mensajes?

0 votos

Nick_g: ¿por qué no querrías obtener el error en el punto donde se ejecuta la llamada al sistema, y obtenerlo de forma asíncrona y mezclado con un montón de otros posibles mensajes de todo tu sistema? ¿Quizás necesitas mejorar tus mecanismos de manejo de errores alrededor de tu código base?

7voto

Dennis Kaarsemaker Puntos 12683

Depende de lo que quieras probar. El uso de un LD_PRELOAD ed, se puede engañar a las aplicaciones para que piensen cosas como "todas las escrituras fallan con ENOSPC o EIO ', por ejemplo.

7voto

Mark Wagner Puntos 11107

Se puede hacer de muchas maneras interesantes. Ver https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt

3 votos

¿Podría destacar las formas "interesantes" relevantes que son específicas para las solicitudes de disco ( fail_make_request )? También sería genial para evitar la putrefacción de los enlaces.

1voto

Jure1873 Puntos 3004

Tal vez podrías cambiar la tabla de particiones y hacer la partición más grande de lo que realmente es. Eso probablemente causaría un error de entrada/salida. O si tus discos son conectables en caliente podrías sacar uno.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: