4

Я создал пять разделов жесткого диска емкостью 1 ТБ (/dev/sda1 , /dev/sdb1 , /dev/sdc1 , /dev/sde1 и /dev/sdf1) в массиве RAID 6 с именем /dev/md0 используя mdadm в Ubuntu 14.04 LTS Верный Тар.

Команда 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 '{if($8~"D"||$8=="STAT"){print $0}}' 
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 продолжает использовать устройство с недействительными данными?

1 ответ1

2

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

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


ответы

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

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

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

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

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

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

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .