web-dev-qa-db-fra.com

Provoquer intentionnellement une erreur d'E / S sous Linux?

Y a-t-il de toute façon, avec Linux, provoquer délibérément un dispositif de blocage de signaler une erreur d'E/S, ou éventuellement simuler un à des fins de test?

42
Dok

Oui, il y a une manière très plausible de le faire avec le mappeur de périphérique.

Le mappeur de périphérique peut recombiner des périphériques de bloc dans une nouvelle cartographie/ordre de votre choix. Lvm fait cela. Il soutient également d'autres objectifs (certains qui sont assez nouveaux) comme "FlakeY" pour simuler un disque défaillant et une "erreur" pour simuler les régions de disque défaillantes.

On peut construire un dispositif qui délibérer a des blackoles IO sur celui-ci qui signaleront des erreurs IO lorsqu'elles sont croisées.

Tout d'abord, créez un volume virtuel à utiliser comme une cible et de le rendre adressable en tant que périphérique de blocage.

dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576
losetup /dev/loop0 /var/lib/virtualblock.img

Donc, pour commencer cela crée un fichier de 512m qui constitue la base de notre dispositif de bloc virtuel que nous allons frapper un "trou". Aucun trou n'existe encore cependant. Si vous étiez à mkfs.ext4 /dev/loop0 Vous obtiendriez un système de fichiers parfaitement valide.

Ainsi, utilisez DMSETUP qui, à l'aide de ce périphérique de bloc - créera un nouveau périphérique qui présente des trous de celui-ci. Voici un exemple en premier

dmsetup create errdev0
0 261144 linear /dev/loop0 0
261144 5 error
261149 787427 linear /dev/loop0 261139

Cela créera un périphérique appelé 'errdev0' (typiquement in/dev/dev/mapper). Lorsque vous tapez dmsetup create errdev0 Il attendra STDIN et finira sur ^ D être entrée.

Dans l'exemple ci-dessus, nous avons effectué un trou de 5 secteurs (2,5 Ko) dans les secteurs 261144 du dispositif de boucle. Nous continuons ensuite à travers l'appareil de boucle normalement.

Ce script tentera de vous générer une table qui placera des trous dans des endroits aléatoires approximativement étendus autour de 16 Mo (bien que son 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 de bloc virtuel est sur /dev/loop0.

Vous pouvez simplement émettre ces données à un fichier texte comme table et tuez-la dans dmsetup create errdev0.

Une fois que vous avez créé le périphérique, vous pouvez alors commencer à l'utiliser comme un périphérique de bloc normal, d'abord en le formatant, puis en plaçant des fichiers dessus. À un moment donné, vous devriez rencontrer des problèmes IO où vous frappez des secteurs qui sont vraiment des trous IO dans le périphérique virtuel.

Une fois que vous avez terminé, utilisez dmsetup remove errdev0 Pour supprimer le périphérique.

Si vous souhaitez que cela soit plus susceptible d'obtenir une erreur IO, vous pouvez ajouter des trous plus fréquemment ou modifier la taille des trous que vous créez. Remarque Mettre des erreurs dans certaines sections est susceptible de causer des problèmes de la goûte, c'est-à-dire à 32 Mo dans un appareil que vous ne pouvez pas écrire un superblock qui tente normalement de le faire. Le format ne fonctionne pas ..

Pour plus d'amusement, vous pouvez en réalité losetup alors mkfs.ext4 /dev/loop0 Et remplissez-le avec des données. Une fois que vous avez un beau système de fichiers de travail sur là, il suffit de démonter le système de fichiers et d'ajouter des trous en utilisant dmsetup et remontez cela!

54
Matthew Ife

Pour vérifier la robustesse du programme au cas où leur sortie échoue, vous pouvez utiliser le pseudodice /dev/full, qui retourne toujours "Enospace" lorsqu'il est écrit à.

$ dd if=/dev/zero of=/dev/full
dd: writing to `/dev/full': No space left on device
1+0 records in
0+0 records out
15

Dépend de ce que vous voulez tester. En utilisant un LD_PRELOADed Bibliothèque, vous pouvez tromper les applications dans la pensée de penser que "toutes les écrivies échouent avec ENOSPC ou EIO 'par exemple.

7
Dennis Kaarsemaker

Vous pouvez le faire dans Oh tellement de manières intéressantes. Voir https://www.kernel.org/doc/documentation/fault-injection/fault-injection.txt

7
Mark Wagner

Peut-être que vous pourriez changer la table de partition et rendre la partition plus grande que c'est vraiment. Cela provoquerait probablement une erreur d'E/S. Ou si vos disques sont chauds, vous pouvez simplement tirer un.

1
Jure1873