Ya hay un gran conjunto de respuestas a esto en 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 VM/dispositivo de bloque Linux/sistema de archivos Linux/biblioteca de espacio de usuario Linux:
- Use los dispositivos de error/flakey/delay/dm-dust de Device Mapper para devolver errores/corrupción o retrasar/dividir IO a un dispositivo de bloque sintetizado (kernel, requiere que el kernel se haya creado con soporte de mapeador de dispositivos, dispositivo adicional apropiado módulos mapeadores (dm-dust solo está disponible en kernel>=5.2) y para tener bits de espacio de usuario del mapeador de dispositivos).
- Use la personalidad defectuosa de md para realizar una inyección de falla periódica en un dispositivo de bloque sintetizado. Ver el
--layout
opción de la página de manual de mdadm para saber cómo configurarlo (bits de espacio de usuario de kernel y mdadm). - Utilice libfiu para realizar la inyección de fallas en las llamadas a la API POSIX (espacio de usuario, se puede usar con
LD_PRELOAD
). - Utilice el inyector de fallas del kernel de Linux para inyectar un error en el dispositivo de bloque subyacente (kernel, requiere que el kernel haya sido construido con
FAIL_MAKE_REQUEST=y
). - Usar SystemTap para realizar la inyección de fallas (kernel, requiere que se haya creado un kernel con muchas cosas).
- Inyecta fallas en el sistema de archivos usando CharybdeFS o PetardFS (espacio de usuario a través de FUSE).
- Cree un dispositivo de bloque sintetizado utilizando el controlador scsi_debug de Linux que realiza la inyección de errores (núcleo).
- Ejecute su sistema dentro de QEMU y use QEMU para inyectar errores de dispositivo de bloque usando el controlador blkdebug (VM).
- Cree un dispositivo de bloque sintetizado a través de las opciones del dispositivo null_blk para inyectar fallas (kernel> =4.14 pero opciones como las probabilidades de tiempo de espera no llegaron hasta 4.17 y requieren que el kernel se haya compilado con
BLK_DEV_NULL_BLK_FAULT_INJECTION=y
). - Cree un dispositivo de bloque de red sintetizado que se sirva al host a través de filtros NBDkit como
delay
oerror
y luego adjunte un dispositivo de bloque a través denbd-client
(kernel + bits de espacio de usuario NBD, kernel>=4.18 construido con soporte NBD, nbdclient>=3.18 y nbdkit>=1.8.1 recomendados - vea el video de demostración de NBDKit alrededor de la marca de 20 minutos).
Dato adicional:SQLite tiene un controlador VFS para simular errores, de modo que pueda obtener una buena cobertura de prueba.
Relacionado:
- ¿Cómo puedo simular un disco fallido durante la prueba?
- ¿Simule un dispositivo de bloque defectuoso con errores de lectura?
- Generar un error de lectura
- ¿Causa intencionalmente un error de E/S en Linux?
Puedes usar dmsetup
para crear un dispositivo mapeador de dispositivos usando el error
o flakey
objetivos para simular fallas.
dmsetup create test --table '0 123 flakey 1 0 /dev/loop0'
Donde 123 es la longitud del dispositivo, en sectores y /dev/loop0 es el dispositivo original en el que desea simular errores. Para error, no necesita los argumentos posteriores ya que siempre devuelve un error.
Quiere 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"):
cat /proc/1234/mem
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 por pensar en /proc/$pid/mem
.
Si usa el PID del proceso en sí, obtiene 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 la mitad del archivo.
Con algo más de configuración como raíz, 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 de su 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 en su mayoría refleja los archivos existentes pero inyecta un EIO en lugares cuidadosamente elegidos. Existe un sistema de archivos de este tipo:petardfs (artículo), no sé qué tan bien funciona desde el primer momento.
Otro método más es un LD_PRELOAD
envoltura. Uno existente es Libfiu (inyección de fallas en el espacio de usuario). Funciona precargando una biblioteca que sobrecarga las llamadas a la API de POSIX. Puede escribir directivas simples o código C arbitrario para anular el comportamiento normal.