Absichtlich einen E / A-Fehler in Linux verursachen?

42

Gibt es unter Linux überhaupt die Möglichkeit, ein Block-Gerät absichtlich dazu zu bringen, einen E / A-Fehler zu melden oder zu Testzwecken zu simulieren?

Dok
quelle
Simulieren Sie einen Festplattenfehler? Vielleicht können Sie ein Verzeichnis einhängen und es dann aushängen, während es verwendet wird.
Shef
2
Ich würde ein kleines Kernelmodul schreiben, mit dem Sie laden könnten modprobe, das sich wie ein Blockgerät verhält, und dann ein anderes kleines Programm, das ioctl()'san den Treiber sendet , damit es den gewünschten Wert zurückgibt.
ott--
Gleiche Frage zu Stack Overlflow und zu Unix und Linux .
Gilles 'SO- hör auf böse zu sein'
Um den Kommentar @Gilles nachzuvollziehen, wurde dieser auch auf stackoverflow.com/questions/1361518/… (verschiedene Antworten zur Fehlerinjektion) und stackoverflow.com/questions/1870696/… (Device Mapper verwenden) abgefragt .
Anon

Antworten:

54

Ja, es gibt eine sehr plausible Möglichkeit, dies mit Device Mapper zu tun.

Der Geräte-Mapper kann Blockgeräte in einer neuen Zuordnung / Reihenfolge Ihrer Wahl neu kombinieren. LVM macht das. Es werden auch andere Ziele (von denen einige recht neu sind) unterstützt, z. B. "Flakey" zum Simulieren einer fehlerhaften Festplatte und "Error" zum Simulieren fehlerhafter Festplattenregionen.

Man kann ein Gerät bauen, das absichtlich IO-Blackholes hat, die IO-Fehler melden, wenn sie gekreuzt werden.

Erstellen Sie zunächst ein virtuelles Volume, das als Ziel verwendet werden soll, und machen Sie es als Blockgerät adressierbar.

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

Um dies zu starten, erstellen wir eine 512-MB-Datei, die die Grundlage für unser virtuelles Block-Gerät ist und in die wir ein 'Loch' stecken. Es ist jedoch noch kein Loch vorhanden. Wenn Sie es mkfs.ext4 /dev/loop0wären, würden Sie ein perfekt gültiges Dateisystem erhalten.

Verwenden wir also dmsetup, das mit diesem Blockgerät ein neues Gerät erstellt, das einige Lücken aufweist. Hier ist zuerst ein Beispiel

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

Dadurch wird ein Gerät mit dem Namen 'errdev0' erstellt (normalerweise in / dev / mapper). Bei dmsetup create errdev0der Eingabe wird auf stdin gewartet und die Eingabe von ^ D beendet.

Im obigen Beispiel haben wir in den Sektoren 261144 des Loop-Geräts ein Loch mit 5 Sektoren (2,5 KB) erstellt. Wir fahren dann wie gewohnt mit dem Loop-Gerät fort.

Dieses Skript wird versuchen, eine Tabelle zu generieren, die Löcher an zufälligen Stellen platziert, die ungefähr 16 MB groß sind (obwohl es ziemlich zufällig ist).

#!/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}"

Das Skript geht davon aus, dass Sie auch ein 512-MB-Gerät erstellt haben und Ihr virtuelles Blockgerät eingeschaltet ist /dev/loop0.

Sie können diese Daten einfach als Tabelle in eine Textdatei ausgeben und in diese umleiten dmsetup create errdev0.

Nachdem Sie das Gerät erstellt haben, können Sie es wie ein normales Blockgerät verwenden, indem Sie es zuerst formatieren und dann Dateien darauf ablegen. Irgendwann sollten Sie auf einige E / A-Probleme stoßen, bei denen Sie auf Sektoren stoßen, die wirklich E / A-Lücken im virtuellen Gerät aufweisen.

Sobald Sie fertig sind dmsetup remove errdev0, entfernen Sie das Gerät.

Wenn Sie die Wahrscheinlichkeit erhöhen möchten, dass ein E / A-Fehler auftritt, können Sie häufiger Löcher hinzufügen oder die Größe der von Ihnen erstellten Löcher ändern. Beachten Sie, dass das Versetzen von Fehlern in bestimmte Abschnitte wahrscheinlich Probleme auf Anhieb verursachen kann. IE bei 32 MB in einem Gerät, für das Sie keinen Superblock schreiben können, was ext normalerweise versucht, sodass das Format nicht funktioniert.

Für zusätzlichen Spaß - Sie können es tatsächlich nur losetupdann mkfs.ext4 /dev/loop0und mit Daten füllen. Wenn Sie ein funktionierendes Dateisystem haben, heben Sie das Dateisystem einfach auf und fügen Sie mit dmsetup einige Lücken hinzu. Hängen Sie das wieder ein!

Matthew Ife
quelle
6
Ich wusste nicht, dass du das kannst. Ziemlich cool.
15

Um die Robustheit des Programms zu überprüfen, falls die Ausgabe fehlschlägt, können Sie das /dev/fullPseudo-Device verwenden, das beim Schreiben immer "ENOSPACE" zurückgibt.

$ 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
quelle
7

Hängt davon ab, was Sie testen möchten. Mithilfe einer LD_PRELOADed-Bibliothek können Sie Anwendungen dazu verleiten, beispielsweise zu denken, dass alle Schreibvorgänge mit ENOSPCoder fehlschlagen EIO.

Dennis Kaarsemaker
quelle
7

Sie können das auf so viele interessante Arten tun. Siehe https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt

Mark Wagner
quelle
3
Könnten Sie die relevanten "interessanten" Möglichkeiten hervorheben, die für Festplattenanforderungen spezifisch sind ( fail_make_request)? Wäre auch toll, Linkfäule zu verhindern.
Deer Hunter
1

Vielleicht könnten Sie die Partitionstabelle ändern und die Partition größer machen, als sie wirklich ist. Das würde wahrscheinlich einen I / O-Fehler verursachen. Oder wenn Ihre Festplatten Hot-Plug-fähig sind, können Sie einfach eine herausziehen.

Jure1873
quelle