Преднамеренно вызвать ошибку ввода-вывода в Linux?

42

Есть ли так или иначе, в Linux, чтобы преднамеренно заставить блочное устройство сообщать об ошибке ввода-вывода или, возможно, имитировать его для целей тестирования?

Dok
источник
Вы симулируете сбой диска? Возможно, вы могли бы смонтировать каталог, а затем размонтировать его, пока он использовался.
Shef
2
Я написал бы небольшой модуль ядра, с которым вы могли бы загружаться modprobe, ведущий себя как блочное устройство, а затем еще одну небольшую программу, которая отправляла ioctl()'sбы драйверу, чтобы он возвращал желаемое значение.
ott--
Тот же вопрос по переполнению стека и по Unix и Linux .
Жиль "ТАК - перестань быть злым"
Чтобы прокомментировать сделанный @Gilles комментарий, его также спросили на stackoverflow.com/questions/1361518/… (несколько разных ответов о внедрении ошибок) и stackoverflow.com/questions/1870696/… (используйте устройство отображения).
Anon

Ответы:

54

Да, есть очень вероятный способ сделать это с помощью устройства отображения.

Устройство сопоставления устройств может объединять блочные устройства в новое сопоставление / порядок по вашему выбору. LVM делает это. Он также поддерживает другие цели (некоторые из которых довольно новы), такие как «flakey» для имитации сбойного диска и «error» для имитации сбойных областей диска.

Можно построить устройство, которое намеренно имеет черные дыры ввода-вывода, которые будут сообщать об ошибках ввода-вывода при пересечении.

Сначала создайте виртуальный том для использования в качестве цели и сделайте его адресуемым как блочное устройство.

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

Итак, для начала создадим файл 512M, который является основой нашего виртуального блочного устройства, в который мы пробьем «дыру». Хотя дыры пока не существует. Если бы вы были, mkfs.ext4 /dev/loop0вы бы получили совершенно правильную файловую систему.

Итак, давайте используем dmsetup, который, используя это блочное устройство, создаст новое устройство, в котором есть некоторые дыры. Вот пример первый

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

Это создаст устройство с именем 'errdev0' (обычно в / dev / mapper). Когда вы печатаете, dmsetup create errdev0он будет ждать ввода stdin и завершится вводом ^ D.

В приведенном выше примере мы сделали отверстие в 5 секторов (2,5 КБ) в секторах 261144 петлевого устройства. Затем мы продолжаем через устройство петли, как обычно.

Этот скрипт попытается сгенерировать вам таблицу, в которой дырки будут размещаться в случайных местах примерно на 16 Мб (хотя это довольно случайно).

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

В сценарии предполагается, что вы также создали устройство объемом 512 МБ и ваше виртуальное блочное устройство включено /dev/loop0.

Вы можете просто вывести эти данные в текстовый файл в виде таблицы и передать их в dmsetup create errdev0.

После того как вы создали устройство, вы можете начать использовать его как обычное блочное устройство, сначала отформатировав его, а затем разместив на нем файлы. В какой-то момент вы столкнетесь с некоторыми проблемами ввода-вывода, когда вы сталкиваетесь с секторами, которые действительно являются дырами ввода-вывода в виртуальном устройстве.

Как только вы закончили использовать dmsetup remove errdev0для удаления устройства.

Если вы хотите повысить вероятность ошибки ввода-вывода, вы можете чаще добавлять отверстия или изменять размер создаваемых отверстий. Обратите внимание, что размещение ошибок в определенных разделах, вероятно, вызовет проблемы с самого начала, т.е. IE на 32 МБ в устройстве, которое вы не можете написать суперблоком, который обычно пытается сделать ext, поэтому формат не будет работать.

Для дополнительного удовольствия - вы можете просто losetupтогда mkfs.ext4 /dev/loop0и заполнить его данными. Когда у вас есть хорошая рабочая файловая система, просто размонтируйте файловую систему и добавьте несколько дырок с помощью dmsetup и перемонтируйте это!

Мэтью Ифе
источник
6
Я не знал, что ты мог сделать это. Довольно круто.
15

Для проверки надежности программы в случае сбоя их вывода вы можете использовать псевдоустройство /dev/full, которое всегда возвращает «ENOSPACE» при записи в.

$ 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
Рауль Салинас-Монтеагудо
источник
7

Зависит от того, что вы хотите проверить. Используя LD_PRELOADбиблиотеку ed, вы можете обмануть приложения, думая, например, что «все записи терпят неудачу ENOSPCили EIO».

Деннис Каарсемакер
источник
7

Вы можете сделать это многими интересными способами. См. Https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt.

Марк Вагнер
источник
3
Не могли бы вы выделить соответствующие «интересные» способы, специфичные для запросов к диску ( fail_make_request)? Также было бы здорово предотвратить гниение ссылок.
Охотник на оленей
1

Может быть, вы могли бы изменить таблицу разделов и сделать раздел больше, чем он есть на самом деле. Это, вероятно, приведет к ошибке ввода-вывода. Или, если ваши диски с возможностью горячей замены, вы можете просто извлечь их.

Jure1873
источник