Deltik, вы неправильно поняли, как работает Linux Software RAID ( md
).
md
создает виртуальное блочное устройство из нескольких устройств или разделов и не знает, какие данные вы передаете на и с виртуального устройства.
Вы надеялись, что он может делать вещи, для которых он не предназначен.
ответы
1. Почему не md
выходит из строя не отвечающий диск / раздел?
Это потому, что md
понятия не имеет,
- накопитель занят вводом / выводом из чего-то, что
md
сам запросил или - диск был заблокирован из-за каких-либо внешних обстоятельств, таких как собственное восстановление диска или в вашем случае ATA Secure Erase,
поэтому md
подождем, чтобы увидеть, что диск вернется. В итоге накопитель не вернул никаких ошибок чтения или записи. Если бы произошла ошибка чтения, md
он автоматически исправил бы ее из-за контроля четности, и если бы произошла ошибка записи, произошел md
бы сбой устройства (см. Раздел «Восстановление» справочной md
страницы ).
Поскольку не было ни ошибки чтения, ни ошибки записи, md
продолжайте использовать устройство после того, как ядро дожидается его ответа.
2. Могу ли я удалить диск / раздел из массива, пока диск заблокирован?
Нет. Устройство /dev/md0
RAID заблокировано и не может быть изменено, пока блок не будет очищен.
Вы передали флаг -f
или --fail
в режим mdadm
«Управление».
Вот пошаговое руководство о том, что это на самом деле делает:
Вот исходный код того, как работает этот флаг :
case 'f': /* set faulty */ /* FIXME check current member */ if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) || (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY, rdev))) { if (errno == EBUSY) busy = 1; pr_err("set device faulty failed for %s: %s\n", dv->devname, strerror(errno)); if (sysfd >= 0) close(sysfd); goto abort; } if (sysfd >= 0) close(sysfd); sysfd = -1; count++; if (verbose >= 0) pr_err("set %s faulty in %s\n", dv->devname, devname); break;
Обратите внимание на звонок write(sysfd, "faulty", 6)
. sysfd
переменная, установленная ранее в файле:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
sysfs_open()
это функция из этого файла :
int sysfs_open(char *devnm, char *devname, char *attr) { char fname[50]; int fd; sprintf(fname, "/sys/block/%s/md/", devnm); if (devname) { strcat(fname, devname); strcat(fname, "/"); } strcat(fname, attr); fd = open(fname, O_RDWR); if (fd < 0 && errno == EACCES) fd = open(fname, O_RDONLY); return fd; }
Если вы будете следовать функциям, вы обнаружите, что по mdadm /dev/md0 -f /dev/sdb1
существу это делает:
echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev
Этот запрос будет ждать и не будет выполнен немедленно, потому что /dev/md0
заблокирован.
3. Можно ли настроить тайм-аут так, чтобы md
автоматически происходил сбой диска, который не отвечает на команды ATA?
Да. Фактически, по умолчанию время ожидания составляет 30 секунд :
root@node51 [~]# cat /sys/block/sdb/device/timeout 30
Проблема с вашим предположением состояла в том, что ваш диск был фактически занят выполнением команды ATA (в течение 188 минут), поэтому время ожидания не истекло.
Подробнее об этом смотрите в документации по обработке ошибок SCSI ядра Linux .
4. Почему md
продолжает использовать устройство с недействительными данными?
Когда ATA Secure Erase завершил работу, накопитель не сообщал о каких-либо проблемах, например, об отмененной команде, поэтому у md
него не было оснований подозревать, что возникла проблема.
Кроме того, в вашем случае использования разделов в качестве устройств RAID вместо целых дисков, таблица разделов ядра в памяти не была проинформирована о том, что раздел на стертом диске исчез, поэтому md
продолжал бы обращаться к вам, /dev/sdb1
как будто ничего не случилось.
Это из md
справочной страницы :
Очистка и несоответствия
Поскольку запоминающие устройства могут создавать поврежденные блоки в любое время, полезно регулярно читать все блоки на всех устройствах в массиве, чтобы своевременно обнаруживать такие поврежденные блоки. Этот процесс называется очисткой .
Массивы md можно очистить, записав либо проверку, либо восстановление в файл md / sync_action в каталоге sysfs для устройства.
Запрос на очистку приведет к тому, что md прочитает каждый блок на каждом устройстве в массиве и проверит соответствие данных. Для RAID1 и RAID10 это означает, что копии идентичны. Для RAID4, RAID5, RAID6 это означает проверку правильности блока четности (или блоков).
Из этого можно сделать вывод, что четность обычно не проверяется при каждом чтении диска. (Кроме того, проверка четности при каждом чтении будет очень сильно снижать производительность, увеличивая количество транзакций, необходимых только для завершения чтения, и проводя сравнение четности с прочитанными данными.)
При нормальной работе md
просто предполагается, что данные, которые он читает, действительны, что делает его уязвимым для повреждения данных без вывода сообщений . В вашем случае у вас был целый диск с незаметно поврежденными данными, потому что вы стерли диск.
Ваша файловая система не знала о повреждении. Вы видели ошибки ввода / вывода на уровне файловой системы, потому что файловая система не могла понять, почему у нее были неверные данные.
Во-первых, чтобы избежать повреждения данных без вывода сообщений, никогда не делайте того, что вы делали снова . Во-вторых, рассмотрите возможность использования ZFS, файловой системы, которая фокусируется на целостности данных, а также обнаруживает и устраняет повреждение данных без вывода сообщений.