Отказ устройства в MD RAID, когда ATA перестает отвечать

1428
Deltik

Я создал пять разделов 1TB HDD ( /dev/sda1, /dev/sdb1, /dev/sdc1, /dev/sde1, и /dev/sdf1) в RAID 6 массива с именем, /dev/md0используя mdadmв Ubuntu 14.04 LTS Trusty тары.

Команда sudo mdadm --detail /dev/md0используется для отображения всех дисков в активной синхронизации .

Затем для тестирования я смоделировал длительную блокировку ввода-вывода /dev/sdb, выполнив эти команды, пока /dev/sdb1он еще был активен в массиве:

hdparm --user-master u --security-set-pass deltik /dev/sdb hdparm --user-master u --security-erase-enhanced deltik /dev/sdb 

ПРЕДУПРЕЖДЕНИЕ

НЕ ПОПРОБУЙТЕ ЭТО НА ДАННЫХ, КОТОРЫЕ ВЫ ЗАБЫВАЕТЕ
В результате этой операции ATA я испортил 455681 inode. Я признаю свою небрежность.

Ожидается, что команда ATA для безопасного стирания будет выполняться в течение 188 минут, блокируя все остальные команды, по крайней мере, в течение этого времени.

Я ожидал mdсбросить диск, который не отвечает, как настоящий RAID-контроллер, но, к моему удивлению, он /dev/md0тоже заблокировался.

mdadm --detail /dev/md0 запрашивает заблокированное устройство, поэтому оно зависает и не выводит.

Вот макет, /proc/mdstatпока я не могу использовать mdadm --detail /dev/md0:

root@node51 [~]# cat /proc/mdstat  Personalities : [raid6] [raid5] [raid4] [linear] [multipath] [raid0] [raid1] [raid10]  md0 : active raid6 sdf1[5] sda1[0] sdb1[4] sdc1[2] sde1[1] 2929887744 blocks super 1.2 level 6, 512k chunk, algorithm 2 [5/5] [UUUUU]  unused devices: <none> 

Я пытался mdadm /dev/md0 -f /dev/sdb1принудительно потерпеть неудачу /dev/sdb1, но это также было заблокировано:

root@node51 [~]# ps aux | awk '}'  USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 3334 1.2 0.0 42564 1800 ? D 03:21 3:37 parted -l root 4957 0.0 0.0 13272 900 ? D 06:19 0:00 mdadm /dev/md0 -f /dev/sdb1 root 5706 0.0 0.0 13388 1028 ? D 06:19 0:00 mdadm --detail /dev/md0 root 7541 0.5 0.0 0 0 ? D Jul19 6:12 [kworker/u16:2] root 22420 0.0 0.0 11480 808 ? D 07:48 0:00 lsblk root 22796 0.0 0.0 4424 360 pts/13 D+ 05:51 0:00 hdparm --user-master u --security-erase-enhanced deltik /dev/sdb root 23312 0.0 0.0 4292 360 ? D 05:51 0:00 hdparm -I /dev/sdb root 23594 0.1 0.0 0 0 ? D 06:11 0:07 [kworker/u16:1] root 25205 0.0 0.0 17980 556 ? D 05:52 0:00 ls --color=auto root 26008 0.0 0.0 13388 1032 pts/23 D+ 06:32 0:00 mdadm --detail /dev/md0 dtkms 29271 0.0 0.2 58336 10412 ? DN 05:55 0:00 python /usr/share/backintime/common/backintime.py --backup-job root 32303 0.0 0.0 0 0 ? D 06:16 0:00 [kworker/u16:0] 

ОБНОВЛЕНИЕ (21 июля 2015 г.): После того, как я ждал полных 188 минут, пока блок ввода-вывода будет очищен, удивление перешло в ужас, когда я увидел, что он mdполностью отключился, /dev/sdbкак если бы он был полностью в такте.

Я думал, mdчто, по крайней мере, увидел бы, что соотношение не соответствует, а затем упал бы /dev/sdb1.

Запаниковав, я mdadm /dev/md0 -f /dev/sdb1снова побежал, и, поскольку блок ввода-вывода был снят, команда быстро завершилась.

Повреждение файловой системы уже происходило из-за ошибок ввода / вывода. Все еще паникуя, я лениво размонтировал раздел данных в RAID-массиве, и с reboot -nfтех пор как решил, что хуже быть не может.

После кусания гвоздя e2fsckна перегородке 455681 inode сделал это lost+found.

С тех пор я пересобрал массив, и сам массив теперь выглядит нормально:

root@node51 [~]# mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Mon Feb 16 14:34:26 2015 Raid Level : raid6 Array Size : 2929887744 (2794.16 GiB 3000.21 GB) Used Dev Size : 976629248 (931.39 GiB 1000.07 GB) Raid Devices : 5 Total Devices : 5 Persistence : Superblock is persistent  Update Time : Tue Jul 21 00:00:30 2015 State : active  Active Devices : 5 Working Devices : 5 Failed Devices : 0 Spare Devices : 0  Layout : left-symmetric Chunk Size : 512K  Name : box51:0 UUID : 6b8a654d:59deede9:c66bd472:0ceffc61 Events : 643541  Number Major Minor RaidDevice State 0 8 1 0 active sync /dev/sda1 1 8 97 1 active sync /dev/sdg1 2 8 33 2 active sync /dev/sdc1 6 8 17 3 active sync /dev/sdb1 5 8 113 4 active sync /dev/sdh1 

Для меня все еще довольно шокирует то, что у меня mdнет двух линий защиты, на которые я рассчитывал:

  • Сбой устройства, когда оно блокируется
  • Сбой устройства, когда данные, которые оно возвращает, являются мусором

Вопросы

  1. Почему не mdвыходит из строя не отвечающий диск / раздел?
  2. Можно ли удалить диск / раздел из массива, пока диск заблокирован?
  3. Можно ли настроить тайм-аут так, чтобы mdавтоматически происходил сбой диска, который не отвечает на команды ATA?
  4. Почему mdпродолжает использовать устройство с недействительными данными?
4

1 ответ на вопрос

2
Deltik

Deltik, вы неправильно поняли, как работает Linux Software RAID ( md).

mdсоздает виртуальное блочное устройство из нескольких устройств или разделов и не знает, какие данные вы передаете на и с виртуального устройства.
Вы надеялись, что он может делать вещи, для которых он не предназначен.


ответы

1. Почему не mdвыходит из строя не отвечающий диск / раздел?

Это потому, что mdпонятия не имеет,

  • накопитель занят вводом / выводом из чего-то, что mdсам запросил или
  • диск был заблокирован из-за каких-либо внешних обстоятельств, таких как собственное восстановление диска или в вашем случае ATA Secure Erase,

поэтому mdподождем, чтобы увидеть, что диск вернется. В итоге накопитель не вернул никаких ошибок чтения или записи. Если бы произошла ошибка чтения, mdон автоматически исправил бы ее из-за контроля четности, и если бы произошла ошибка записи, произошел mdбы сбой устройства (см. Раздел «Восстановление» справочной mdстраницы ).

Поскольку не было ни ошибки чтения, ни ошибки записи, mdпродолжайте использовать устройство после того, как ядро ​​дожидается его ответа.

2. Могу ли я удалить диск / раздел из массива, пока диск заблокирован?

Нет. Устройство /dev/md0RAID заблокировано и не может быть изменено, пока блок не будет очищен.

Вы передали флаг -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, файловой системы, которая фокусируется на целостности данных, а также обнаруживает и устраняет повреждение данных без вывода сообщений.

Похожие вопросы