Falha no dispositivo no md RAID quando o ATA para de responder

Falha no dispositivo no md RAID quando o ATA para de responder

eu tinha criadocinco partições HDD de 1 TB( /dev/sda1, /dev/sdb1, /dev/sdc1, /dev/sde1, e /dev/sdf1) em umRAID 6array chamado /dev/md0usando mdadmno Ubuntu 14.04 LTS Trusty Tahr.

O comando sudo mdadm --detail /dev/md0usado para mostrar todas as unidades emsincronização ativa.

Então, para teste, simulei um longo bloqueio de E/S /dev/sdbexecutando estes comandos enquanto /dev/sdb1ainda estava ativo no array:

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

AVISO

NÃO TENTE ISSO COM DADOS QUE VOCÊ SE IMPORTA!
Acabei corrompendo 455681 inodes como resultado desta operação ATA. Admito minha negligência.

Esperava-se que o comando ATA para apagamento seguro fosse executado por 188 minutos, bloqueando todos os outros comandos por pelo menos esse tempo.

Eu esperava mddescartar a unidade que não respondia como um controlador RAID adequado, mas, para minha surpresa, /dev/md0também ficou bloqueado.

mdadm --detail /dev/md0consulta o dispositivo bloqueado, então ele congela e não gera saída.

Aqui está o layout /proc/mdstatenquanto não posso usar 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>

Tentei mdadm /dev/md0 -f /dev/sdb1falhar à força /dev/sdb1, mas também foi bloqueado:

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]

ATUALIZAÇÃO (21 de julho de 2015):Depois de esperar 188 minutos completos para que o bloco de E/S fosse limpo, a surpresa se transformou em horror quando vi que mdtratava o bloco completamente apagado /dev/sdbcomo se estivesse completamente intacto.

Achei que mdpelo menos teria visto que a paridade estava incompatível e depois teria caído /dev/sdb1.

Em pânico, corri mdadm /dev/md0 -f /dev/sdb1novamente e, como o bloco de E/S foi suspenso, o comando foi concluído rapidamente.

A corrupção do sistema de arquivos já estava acontecendo à medida que surgiam erros de entrada/saída. Ainda em pânico, desmontei preguiçosamente a partição de dados na matriz RAID e reboot -nfpercebi que não poderia piorar.

Depois de roer as unhas e2fsckna partição, 455.681 inodes chegaram ao arquivo lost+found.

Desde então, remontei o array, e o array em si parece bom agora:

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

Ainda é um grande choque para mim mdnão ter duas linhas de proteção que eu esperava:

  • Falha em um dispositivo quando ele trava
  • Falha em um dispositivo quando os dados que ele retorna são lixo

Questões

  1. Por que mda unidade/partição que não responde falha?
  2. Posso eliminar a unidade/partição do array enquanto a unidade estiver bloqueada?
  3. Um tempo limite pode ser configurado para mdfalhar automaticamente em uma unidade que não está respondendo aos comandos ATA?
  4. Por que mdcontinua usando um dispositivo com dados inválidos?

Responder1

Deltik, você não entendeu como o Linux Software RAID ( md) funciona.

mdcria um dispositivo de bloco virtual a partir de vários dispositivos ou partições e não tem conhecimento de quais dados você está transferindo de e para o dispositivo virtual.
Você esperava que ele pudesse fazer coisas para as quais não foi projetado.


Respostas

1. Por que mda unidade/partição que não responde falha?

Isso ocorre porque mdnão tem ideia se

  • a unidade está ocupada com E/S de algo que mdsolicitou ou
  • a unidade foi bloqueada devido a alguma circunstância externa, como a recuperação de erros da própria unidade ou, no seu caso, um ATA Secure Erase,

então mdvamos esperar para ver o que a unidade retorna. A unidade eventualmente não retornou nenhum erro de leitura ou gravação. Se houvesse um erro de leitura, o mddispositivo teria sido corrigido automaticamente da paridade, e se houvesse um erro de gravação, mdo dispositivo teria falhado (veja a seção "Recuperação" domdpágina de manual).

Como não houve erro de leitura nem de gravação, mdcontinuei usando o dispositivo depois que o kernel esperou que ele respondesse.

2. Posso eliminar a unidade/partição do array enquanto a unidade estiver bloqueada?

Não. O /dev/md0dispositivo RAID está bloqueado e não pode ser modificado até que o bloqueio seja limpo.

Você passou o sinalizador -fou --failpara o mdadmmodo "Gerenciar".
Aqui está um passo a passo do que isso realmente faz:

Este é o código fonte de como esse sinalizador funciona:

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;

Observe a chamada write(sysfd, "faulty", 6). sysfdé uma variável definida anteriormente no arquivo:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");

sysfs_open()é uma função deeste ficheiro:

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;
}

Se você seguir as funções, descobrirá que mdadm /dev/md0 -f /dev/sdb1basicamente faz isso:

echo "faulty" > /sys/block/md0/md/dev-sdb1/block/dev

Esta solicitação estará aguardando e não será processada imediatamente porque /dev/md0está bloqueada.

3. Um tempo limite pode ser configurado para mdfalhar automaticamente em uma unidade que não está respondendo aos comandos ATA?

Sim. Na verdade,por padrão, o tempo limite é de 30 segundos:

root@node51 [~]# cat /sys/block/sdb/device/timeout
30

O problema com sua suposição era que sua unidade estava realmente ocupada executando um comando ATA (por 188 minutos), portanto o tempo limite não estava esgotado.

Para obter detalhes sobre isso, consulte oDocumentação de tratamento de erros SCSI do kernel Linux.

4. Por que mdcontinua usando um dispositivo com dados inválidos?

Quando o ATA Secure Erase foi concluído, a unidade não relatou nenhum problema, como um comando abortado, portanto mdnão havia motivo para suspeitar que havia um problema.

Além disso, no caso de usar partições como dispositivos RAID em vez de discos inteiros, a tabela de partições na memória do kernel não foi informada de que a partição na unidade apagada havia desaparecido, então mdcontinuaria a acessá-la /dev/sdb1como se nada estivesse errado.

Isto é domdpágina de manual:

Esfregando e incompatibilidades

Como os dispositivos de armazenamento podem desenvolver blocos defeituosos a qualquer momento, é valioso ler regularmente todos os blocos em todos os dispositivos de uma matriz para detectar esses blocos defeituosos antecipadamente. Este processo é chamadoesfregando.

Matrizes md podem ser limpas escrevendoverificarourepararpara o arquivomd/sync_actionnosysfsdiretório do dispositivo.

Solicitar uma limpeza fará com que o md leia todos os blocos em todos os dispositivos da matriz e verifique se os dados são consistentes. Para RAID1 e RAID10, isso significa verificar se as cópias são idênticas. Para RAID4, RAID5, RAID6, isso significa verificar se o bloco de paridade está (ou os blocos estão) corretos.

Podemos inferir disso que a paridade normalmente não é verificada em todas as leituras do disco. (Além disso, verificar a paridade em cada leitura seria muito desgastante para o desempenho, pois aumentaria as transações necessárias apenas para concluir uma leitura e executaria a comparação da paridade com os dados lidos.)

Em operação normal, mdapenas assume que os dados que está lendo são válidos, deixando-o vulnerável acorrupção silenciosa de dados. No seu caso, você tinha uma unidade inteira com dados corrompidos silenciosamente porque apagou a unidade.

Seu sistema de arquivos não estava ciente da corrupção. Você viu erros de entrada/saída no nível do sistema de arquivos porque o sistema de arquivos não conseguia entender por que havia dados incorretos.

Para evitar a corrupção silenciosa de dados, primeiro,nunca mais faça o que você fez. Em segundo lugar, considere usarZFS, um sistema de arquivos que se concentra na integridade dos dados e detecta e corrige a corrupção silenciosa de dados.

informação relacionada