43 votes

Intentionnellement provoquer une erreur d'E/S dans Linux ?

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 ?

54voto

Matthew Ife Points 22370

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 !

16voto

Benjie Points 3416

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

7voto

jowi Points 111

Dépend de ce que vous voulez tester. En utilisant une bibliothèque préchargée LD_PRELOAD, vous pouvez tromper les applications en leur faisant croire des choses comme 'toutes les écritures échouent avec ENOSPC ou EIO' par exemple.

7voto

songsong Points 173

Vous pouvez le faire de tant de façons intéressantes. Voir https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt

1voto

Jure1873 Points 3672

Peut-être pourriez-vous changer la table de partition et agrandir la partition pour qu'elle soit réellement plus grande. Cela pourrait probablement provoquer une erreur d'E/S. Ou si vos disques sont amovibles à chaud, vous pourriez simplement en retirer un.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X