Y a-t-il un moyen, avec Linux, de provoquer délibérément qu'un périphérique de bloc signale une erreur d'E/S, ou éventuellement d'en simuler une à des fins de test ?
Réponses
Trop de publicités?Oui, il existe un moyen très plausible de faire cela avec le gestionnaire de périphériques.
Le gestionnaire de périphériques peut recombiner des périphériques bloc dans un nouvel ordre/mappage de votre choix. LVM le fait. Il prend également en charge d'autres cibles (dont certaines sont assez novatrices) comme 'flakey' pour simuler un disque défaillant et 'error' pour simuler des régions défaillantes du disque.
On peut créer un périphérique délibérément avec des trous noirs d'E/S qui rapporteront des erreurs d'E/S lorsqu'ils sont traversés.
Tout d'abord, créez un volume virtuel à utiliser comme cible et rendez-le adressable en tant que périphérique bloc.
dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576
losetup /dev/loop0 /var/lib/virtualblock.img
Alors, pour commencer, cela crée un fichier de 512 Mo qui est la base de notre périphérique bloc virtuel dans lequel nous allons créer un 'trou'. Cependant, aucun trou n'existe encore. Si vous deviez mkfs.ext4 /dev/loop0
, vous obtiendriez un système de fichiers parfaitement valide.
Alors, utilisons dmsetup qui, en utilisant ce périphérique bloc -- va créer un nouveau périphérique avec des trous. Voici un premier exemple
dmsetup create errdev0
0 261144 linear /dev/loop0 0
261144 5 error
261149 787427 linear /dev/loop0 261139
Cela va créer un périphérique appelé 'errdev0' (généralement dans /dev/mapper). Lorsque vous tapez dmsetup create errdev0
, il attendra l'entrée standard et se terminera lors de la saisie de ^D.
Dans l'exemple ci-dessus, nous avons créé un trou de 5 secteurs (2,5 ko) aux secteurs 261144 du périphérique en boucle. Nous continuons ensuite à traverser le périphérique en boucle normalement.
Ce script tentera de vous générer une table qui placera des trous à des emplacements aléatoires environ répartis autour de 16 Mo (bien que ce soit assez aléatoire).
#!/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}"
Le script suppose que vous avez également créé un périphérique de 512 Mo et que votre périphérique bloc virtuel se trouve sur /dev/loop0
.
Vous pouvez simplement sortir ces données dans un fichier texte en tant que table et les rediriger vers dmsetup create errdev0
.
Une fois que vous avez créé le périphérique, vous pouvez ensuite commencer à l'utiliser comme un périphérique bloc normal, d'abord en le formatant, puis en y plaçant des fichiers. À un moment donné, vous devriez rencontrer des problèmes d'E/S lorsque vous atteignez des secteurs qui sont réellement des trous d'E/S dans le périphérique virtuel.
Une fois terminé, utilisez dmsetup remove errdev0
pour supprimer le périphérique.
Si vous souhaitez augmenter la probabilité d'obtenir une erreur d'E/S, vous pouvez ajouter des trous plus fréquemment ou changer la taille des trous que vous créez. Notez que mettre des erreurs dans certaines sections est susceptible de provoquer des problèmes dès le départ, par exemple à 32 Mo dans un périphérique vous ne pouvez pas écrire un superbloc que ext tente normalement de faire, donc le formatage ne fonctionnera pas..
Pour plus de plaisir -- vous pouvez en fait simplement losetup
puis mkfs.ext4 /dev/loop0
et le remplir de données. Une fois que vous avez un joli système de fichiers fonctionnel là-dessus, démontez simplement le système de fichiers, ajoutez quelques trous en utilisant dmsetup et remontez-le !
Pour vérifier la robustesse du programme en cas d'échec de sa sortie, vous pouvez utiliser le pseudodispositif /dev/full
, qui renvoie toujours "ENOSPACE" lorsqu'il est écrit.
$ dd if=/dev/zero of=/dev/full
dd: écriture sur '/dev/full' : Aucun espace disponible sur le périphérique
1+0 enregistrements lus
0+0 enregistrements écrits
Vous pouvez le faire de tant de façons intéressantes. Voir https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt