Есть ли способ в 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_PRELOAD
ed, вы можете заставить приложения думать, что ENOSPC
или EIO
' например.
Вы можете сделать это множеством интересных способов. Видеть https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt
Возможно, вы могли бы изменить таблицу разделов и сделать раздел больше, чем он есть на самом деле. Это, вероятно, вызовет ошибку ввода-вывода. Или, если ваши диски поддерживают горячую замену, вы можете просто вытащить один из них.