Quiero probar automáticamente si una pieza de software reacciona como se esperaba si un archivo esencial de SQLite DB no se puede leer (causando un error de E / S). Exactamente eso sucedió hace unos días en un cliente. Lo arreglamos manualmente, pero ahora quiero crear un código automático para arreglarlo y necesito acceso a un archivo roto para probarlo.
Como todo en Unix es un archivo, sospeché que podría haber un archivo especial que siempre causa errores de E / S cuando uno intenta leerlo (por ejemplo, en / dev).
Algunos archivos similares (imo) serían:
/dev/full
que siempre dice "No queda espacio en el dispositivo" si intentas escribirlo/dev/null
y/dev/zero
así que supuse que solo tenía que haber un archivo como ese (pero aún no he encontrado uno).
¿Alguien conoce ese archivo o cualquier otro método para obtener el resultado deseado (una imagen de partición intencionalmente defectuosa, un contenedor alrededor de open () usando LD_PRELOAD, ...)?
¿Cuál es la mejor manera de ir aquí?
Respuestas:
Puede usar
dmsetup
para crear un dispositivo de mapeador de dispositivos usando los objetivoserror
oflakey
para simular fallas.Donde 123 es la longitud del dispositivo, en sectores y / dev / loop0 es el dispositivo original en el que desea simular errores. Por error, no necesita los argumentos posteriores ya que siempre devuelve un error.
fuente
dmsetup table test
. Incluso puedes escribirfoo bar
detráserror
; simplemente no le importa (y, por lo tanto, debería eliminarse).Ya hay un gran conjunto de respuestas sobre Stack Overflow y Server Fault, pero faltaban algunas técnicas. Para hacer la vida más fácil, aquí hay una lista de mecanismos de inyección de fallas de E / S de dispositivos de bloques VM / Linux / sistema de archivos Linux / biblioteca de espacio de usuario de Linux:
--layout
opción de la página de manual mdadm para saber cómo configurarlo (kernel y bits de espacio de usuario mdadm).LD_PRELOAD
).FAIL_MAKE_REQUEST=y
).BLK_DEV_NULL_BLK_FAULT_INJECTION=y
).delay
oerror
y luego adjunte un dispositivo de bloqueo a través denbd-client
(kernel + NBD userspace bits, kernel> = 4.18 construido con soporte NBD, nbdclient> = 3.18 y nbdkit> = 1.8.1 recomendado: vea el video de demostración de NBDKit alrededor de los 20 minutos).Dato adicional : SQLite tiene un controlador VFS para simular errores para que pueda obtener una buena cobertura de prueba.
Relacionado:
fuente
Desea un mecanismo de inyección de fallas para E / S.
En Linux, aquí hay un método que no requiere ninguna configuración previa y genera un error inusual (no EIO "Error de entrada / salida" sino ESRCH "No existe tal proceso"):
donde 1234 es el PID de un proceso que se ejecuta como el mismo usuario que el proceso que está probando, pero no ese proceso en sí. Créditos a rubasov para pensar de
/proc/$pid/mem
.Si usa el PID del proceso en sí, obtendrá EIO, pero solo si está leyendo desde un área que no está asignada en la memoria del proceso. La primera página nunca se asigna, por lo que está bien si lee el archivo secuencialmente, pero no es adecuado para un proceso de base de datos que busca directamente en el medio del archivo.
Con algo más de configuración como root, puede aprovechar el mapeador de dispositivos para crear archivos con sectores válidos y sectores defectuosos.
Otro enfoque sería implementar un pequeño sistema de archivos FUSE . EIO es el código de error predeterminado cuando el controlador del sistema de archivos del espacio de usuario hace algo mal, por lo que es fácil de lograr. Tanto los enlaces de Perl como los de Python vienen con ejemplos para comenzar, puede escribir rápidamente un sistema de archivos que refleje principalmente los archivos existentes pero inyecta un EIO en lugares cuidadosamente seleccionados. Existe un sistema de archivos de este tipo: petardfs ( artículo ), no sé qué tan bien funciona fuera de la caja.
Otro método más es un
LD_PRELOAD
envoltorio. Uno existente es Libfiu (inyección de fallas en el espacio de usuario). Funciona precargando una biblioteca que sobrecarga las llamadas a la API POSIX. Puede escribir directivas simples o código C arbitrario para anular el comportamiento normal.fuente
La solución es mucho más fácil si está bien usar un archivo de dispositivo como "archivo con errores de E / S". Mi propuesta es para aquellos casos en los que un archivo normal tendrá tales errores.
Debo admitir que estoy un poco confundido porque no he logrado leer sectores individuales de ese archivo sin un error (con
dd .. seek=...
). Quizás sea un problema de lectura anticipada.fuente
Puede usar CharybdeFS que fue hecho exactamente para este tipo de propósito.
Es un sistema de archivos de fusibles pasivo como PetardFS pero mucho más configurable.
Vea el libro de cocina CharybdeFS aquí: http://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/
Es lo suficientemente avanzado como para probar una base de datos.
fuente