Il existe déjà un grand nombre de réponses à cela sur Stack Overflow et Server Fault, mais certaines techniques manquaient. Pour vous faciliter la vie, voici une liste des mécanismes d'injection de fautes d'E/S de VM/Linux block device/Linux filesystem/Linux userspace library :
- Utilisez les périphériques d'erreur/flakey/delay/dm-dust de Device Mapper pour renvoyer les erreurs/la corruption depuis, ou retarder/diviser les E/S vers un périphérique de bloc synthétisé (noyau, nécessite que le noyau ait été construit avec la prise en charge du mappeur de périphérique, un périphérique supplémentaire approprié modules de mappage (dm-dust n'est disponible que sur le noyau> =5.2) et pour avoir des bits d'espace utilisateur du mappeur de périphérique).
- Utilisez la personnalité défectueuse de md pour effectuer une injection périodique de fautes sur un périphérique de bloc synthétisé. Voir le
--layout
option de la page de manuel mdadm pour savoir comment le configurer (noyau et bits de l'espace utilisateur mdadm). - Utilisez libfiu pour effectuer l'injection de fautes sur les appels d'API POSIX (espace utilisateur, peut être utilisé avec
LD_PRELOAD
). - Utilisez l'injecteur d'erreurs du noyau Linux pour injecter une erreur dans le périphérique de bloc sous-jacent (noyau, nécessite que le noyau ait été construit avec
FAIL_MAKE_REQUEST=y
). - Utiliser SystemTap pour faire l'injection de fautes (noyau, nécessite qu'un noyau ait été construit avec beaucoup de choses).
- Injecter les erreurs du système de fichiers à l'aide de CharybdeFS ou PetardFS (espace utilisateur via FUSE).
- Créer un périphérique bloc synthétisé à l'aide du pilote Linux scsi_debug qui effectue l'injection de fautes (noyau).
- Exécutez votre système dans QEMU et utilisez QEMU pour injecter des erreurs de périphérique de bloc à l'aide du pilote blkdebug (VM).
- Créer un périphérique bloc synthétisé via les options du périphérique null_blk pour injecter des défauts (kernel>=4.14 mais des options comme les probabilités d'expiration ne sont pas arrivées avant 4.17 et nécessitent que le noyau ait été construit avec
BLK_DEV_NULL_BLK_FAULT_INJECTION=y
). - Créer un périphérique de bloc réseau synthétisé qui est servi à l'hôte via des filtres NBDkit tels que
delay
ouerror
puis attachez-lui un périphérique de bloc vianbd-client
(noyau + bits d'espace utilisateur NBD, noyau>=4.18 construit avec le support NBD, nbdclient>=3.18 et nbdkit>=1.8.1 recommandés - voir la vidéo de démonstration NBDKit autour de la barre des 20 minutes).
Fait bonus :SQLite dispose d'un pilote VFS pour simuler les erreurs afin d'obtenir une bonne couverture de test.
Connexe :
- Comment puis-je simuler un disque défaillant pendant les tests ?
- Simulez un périphérique de bloc défectueux avec des erreurs de lecture ?
- Générer une erreur de lecture
- Provoque intentionnellement une erreur d'E/S sous Linux ?
Vous pouvez utiliser dmsetup
pour créer un périphérique device-mapper en utilisant soit le error
ou flakey
cibles pour simuler des pannes.
dmsetup create test --table '0 123 flakey 1 0 /dev/loop0'
Où 123 est la longueur du périphérique, en secteurs et /dev/loop0 est le périphérique d'origine sur lequel vous souhaitez simuler les erreurs. En cas d'erreur, vous n'avez pas besoin des arguments suivants car ils renvoient toujours une erreur.
Vous voulez un mécanisme d'injection de fautes pour les E/S.
Sous Linux, voici une méthode qui ne nécessite aucune configuration préalable et génère une erreur inhabituelle (pas EIO "Erreur d'entrée/sortie" mais ESRCH "No such process") :
cat /proc/1234/mem
où 1234 est le PID d'un processus exécuté sous le même utilisateur que le processus que vous testez, mais pas ce processus lui-même. Remerciements à rubasov pour avoir pensé à /proc/$pid/mem
.
Si vous utilisez le PID du processus lui-même, vous obtenez EIO, mais uniquement si vous lisez à partir d'une zone qui n'est pas mappée dans la mémoire du processus. La première page n'est jamais mappée, donc ce n'est pas grave si vous lisez le fichier de manière séquentielle, mais cela ne convient pas à un processus de base de données qui cherche directement au milieu du fichier.
Avec un peu plus de configuration en tant que root, vous pouvez tirer parti du mappeur de périphérique pour créer des fichiers avec des secteurs valides et des secteurs défectueux.
Une autre approche consisterait à implémenter un petit système de fichiers FUSE. EIO est le code d'erreur par défaut lorsque votre pilote de système de fichiers en espace utilisateur fait quelque chose de mal, il est donc facile à réaliser. Les liaisons Perl et Python sont fournies avec des exemples pour commencer, vous pouvez rapidement écrire un système de fichiers qui reflète principalement les fichiers existants mais injecte un EIO dans des endroits soigneusement choisis. Il existe un tel système de fichiers :petardfs (article), je ne sais pas si cela fonctionne correctement.
Encore une autre méthode est un LD_PRELOAD
emballage. Un existant est Libfiu (injection de fautes dans l'espace utilisateur). Cela fonctionne en préchargeant une bibliothèque qui surcharge les appels d'API POSIX. Vous pouvez écrire des directives simples ou du code C arbitraire pour remplacer le comportement normal.