Назад | Перейти на главную страницу

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

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

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

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

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

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

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

Итак, для начала создается файл размером 512 МБ, который является основой нашего виртуального блочного устройства, в котором мы проделаем «дыру». Однако дыры еще не существует. Если бы вы были 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 удалить устройство.

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

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

Для проверки работоспособности программы в случае сбоя ее вывода можно использовать псевдоустройство /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

Зависит от того, что вы хотите протестировать. Используя LD_PRELOADed, вы можете заставить приложения думать, что ENOSPC или EIO' например.

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

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