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

42

Existe-t-il de toute façon, avec Linux, pour obliger un périphérique en mode bloc à signaler une erreur d’entrée / sortie, ou éventuellement à en simuler une à des fins de test?

Dok
la source
Vous simulez une panne de disque? Vous pourriez peut-être monter un répertoire, puis le démonter pendant son utilisation.
Shef
2
J'écrirais un petit module de noyau que vous pourriez charger modprobe, se comportant comme un périphérique en mode bloc, puis un autre petit programme qui envoie ioctl()'sau pilote pour lui faire renvoyer la valeur souhaitée.
Out--
Même question sur Stack Overlflow , Unix et Linux .
Gilles, arrête de faire le mal '29
Pour faire suite au commentaire que @Gilles a fait, cela a également été demandé sur stackoverflow.com/questions/1361518/… (plusieurs réponses à une injection de faute) et sur stackoverflow.com/questions/1870696/… (utilisez le mappeur de périphérique).
Anon

Réponses:

54

Oui, il existe un moyen très plausible de faire cela avec Device Mapper.

Le mappeur de périphérique peut recombiner des périphériques en mode bloc dans un nouveau mappage / ordre de votre choix. LVM le fait. Il prend également en charge d’autres cibles (certaines assez nouvelles) telles que «floconneuse» pour simuler un disque défaillant et «erreur» pour simuler des régions de disque défaillantes.

Il est possible de construire un périphérique dont les points noirs IO sont délibérément signalés et qui signaleront les erreurs IO lorsqu’ils seront croisés.

Commencez par créer un volume virtuel à utiliser en tant que cible et en le rendant adressable en tant que périphérique en mode bloc.

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 périphérique de bloc virtuel dans lequel nous allons percer un "trou". Aucun trou n’existe pour le moment. Si vous mkfs.ext4 /dev/loop0deviez le faire, vous obtiendrez un système de fichiers parfaitement valide.

Donc, utilisons dmsetup qui, en utilisant ce périphérique bloc - créera un nouveau périphérique qui comporte des trous. Voici un exemple d'abord

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' (généralement dans / dev / mapper). Lorsque vous tapez, dmsetup create errdev0il attend stdin et se termine lorsque ^ D est entré.

Dans l'exemple ci-dessus, nous avons créé un trou de 5 secteurs (2,5 Ko) au niveau des secteurs 261144 du dispositif de boucle. Nous continuons ensuite à travers le périphérique de boucle comme d’habitude.

Ce script tentera de vous générer une table qui placera des trous à des emplacements aléatoires répartis approximativement autour de 16 Mo (bien que ce soit plutôt 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 activé /dev/loop0.

Vous pouvez simplement exporter ces données dans un fichier texte sous forme de tableau et les canaliser dmsetup create errdev0.

Une fois que vous avez créé le périphérique, vous pouvez commencer à l'utiliser comme un périphérique en mode bloc, en le formatant d'abord, puis en y plaçant des fichiers. À un moment donné, vous devriez rencontrer des problèmes d'E / S dans lesquels vous touchez des secteurs qui sont vraiment des trous d'E / S dans le périphérique virtuel.

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

Si vous souhaitez augmenter les risques d’erreurs IO, vous pouvez ajouter des trous plus fréquemment ou modifier la taille des trous créés. Notez que mettre des erreurs dans certaines sections est susceptible de causer des problèmes dès le départ, IE à 32 Mo dans un appareil que vous ne pouvez pas écrire dans un superbloc que ext essaie normalement de faire, de sorte que le format ne fonctionnera pas.

Pour plus de plaisir, vous pouvez le faire à ce moment- losetupmkfs.ext4 /dev/loop0et le remplir de données. Une fois que vous avez un bon système de fichiers, démontez-le simplement, ajoutez des trous à l'aide de dmsetup et remontez-le!

Matthew Ife
la source
6
Je ne savais pas que tu pouvais faire ça. Plutôt cool.
15

Pour vérifier la robustesse du programme en cas d'échec de la sortie, vous pouvez utiliser le pseudodevice /dev/full, qui renvoie 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
Raúl Salinas-Monteagudo
la source
7

Cela dépend de ce que vous voulez tester. En utilisant une LD_PRELOADbibliothèque ed, vous pouvez amener les applications à penser des choses telles que «toutes les écritures échouent ENOSPCou EIO», par exemple.

Dennis Kaarsemaker
la source
1

Peut-être pourriez-vous changer la table de partition et agrandir la partition telle qu'elle est réellement. Cela provoquerait probablement une erreur d'entrée-sortie. Ou, si vos disques sont connectables à chaud, vous pouvez simplement en retirer un.

Jure1873
la source