Dispositivo fallido en md RAID cuando ATA deja de responder

Dispositivo fallido en md RAID cuando ATA deja de responder

yo había creadocinco particiones HDD de 1 TB( /dev/sda1, /dev/sdb1, /dev/sdc1, /dev/sde1, y /dev/sdf1) en unRAID 6matriz llamada /dev/md0usando mdadmen Ubuntu 14.04 LTS Trusty Tahr.

El comando sudo mdadm --detail /dev/md0utilizado para mostrar todas las unidades ensincronización activa.

Luego, para realizar pruebas, simulé un bloqueo de E/S prolongado /dev/sdbejecutando estos comandos mientras /dev/sdb1todavía estaba activo en la matriz:

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

ADVERTENCIA

¡NO INTENTE ESTO CON DATOS QUE LE IMPORTAN!
Terminé corrompiendo 455681 inodos como resultado de esta operación ATA. Admito mi negligencia.

Se esperaba que el comando ATA para borrado seguro se ejecutara durante 188 minutos, bloqueando todos los demás comandos durante al menos ese tiempo.

Esperaba mdsoltar la unidad que no respondía como si fuera un controlador RAID adecuado, pero, para mi sorpresa, /dev/md0también se bloqueó.

mdadm --detail /dev/md0consulta el dispositivo bloqueado, por lo que se congela y no genera salida.

Aquí está el diseño /proc/mdstatmientras no puedo usarlo 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>

Intenté mdadm /dev/md0 -f /dev/sdb1fallar con fuerza /dev/sdb1, pero eso también fue 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]

ACTUALIZACIÓN (21 de julio de 2015):Después de esperar los 188 minutos completos para que se borrara el bloque de E/S, la sorpresa se convirtió en horror cuando vi que mdtrataban el bloque completamente en blanco /dev/sdbcomo si estuviera completamente intacto.

Pensé que así mdal menos se habría visto que la paridad no coincidía y entonces habría bajado /dev/sdb1.

Entrando en pánico, volví a correr mdadm /dev/md0 -f /dev/sdb1y, como se había levantado el bloqueo de E/S, el comando se completó rápidamente.

La corrupción del sistema de archivos ya estaba ocurriendo a medida que surgían errores de entrada/salida. Aún entrando en pánico, desmonté lentamente la partición de datos en la matriz RAID y reboot -nfpensé que no podía empeorar.

Después de morderse las uñas e2fscken la partición, 455681 inodos llegaron a lost+found.

Desde entonces, volví a ensamblar la matriz y la matriz en sí se ve bien ahora:

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

Todavía me sorprende mucho que mdno tenga las dos líneas de protección que esperaba:

  • Fallar un dispositivo cuando se bloquea
  • Fallar un dispositivo cuando los datos que devuelve son basura

Preguntas

  1. ¿Por qué no mdfalla la unidad/partición que no responde?
  2. ¿Puedo quitar la unidad/partición del arreglo mientras la unidad está bloqueada?
  3. ¿Se puede configurar un tiempo de espera para que mdfalle automáticamente una unidad que no responde a los comandos ATA?
  4. ¿Por qué se mdsigue utilizando un dispositivo con datos no válidos?

Respuesta1

Deltik, no ha entendido bien cómo mdfunciona el software RAID ( ) de Linux.

mdcrea un dispositivo de bloque virtual a partir de múltiples dispositivos o particiones y no tiene conocimiento de qué datos está transfiriendo hacia y desde el dispositivo virtual.
Esperabas que pudiera hacer cosas para las que no fue diseñado.


Respuestas

1. ¿Por qué no mdfalla la unidad/partición que no responde?

Esto se debe a que mdno tiene idea de si

  • la unidad está ocupada con E/S de algo que mdél mismo solicitó o
  • la unidad se bloqueó debido a alguna circunstancia externa, como la propia recuperación de errores de la unidad o, en su caso, un borrado seguro ATA,

Así que mdesperaré a ver qué devuelve el disco. La unidad finalmente no arrojó ningún error de lectura o escritura. Si hubiera un error de lectura, mdlo habría arreglado automáticamente desde la paridad, y si hubiera un error de escritura, mdhabría fallado el dispositivo (ver la sección "Recuperación" delmdpágina de manual).

Como no hubo ningún error de lectura ni de escritura, mdcontinuó usando el dispositivo después de que el kernel esperó a que respondiera.

2. ¿Puedo quitar la unidad/partición del arreglo mientras la unidad está bloqueada?

No. El /dev/md0dispositivo RAID está bloqueado y no se puede modificar hasta que se borre el bloqueo.

Pasaste la bandera -fo --failal mdadmmodo "Administrar".
Aquí hay un tutorial de lo que realmente hace:

Este es el código fuente de cómo funciona esa bandera.:

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;

Note la llamada write(sysfd, "faulty", 6). sysfdes una variable establecida anteriormente en el archivo:
sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");

sysfs_open()es una función deEste archivo:

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

Si sigues las funciones, encontrarás que mdadm /dev/md0 -f /dev/sdb1básicamente hace esto:

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

Esta solicitud estará esperando y no se procesará de inmediato porque /dev/md0está bloqueada.

3. ¿Se puede configurar un tiempo de espera para que mdfalle automáticamente una unidad que no responde a los comandos ATA?

Sí. De hecho,De forma predeterminada, el tiempo de espera es de 30 segundos.:

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

El problema con su suposición fue que su unidad estaba realmente ocupada ejecutando un comando ATA (durante 188 minutos), por lo que no se agotó el tiempo de espera.

Para obtener detalles sobre esto, consulte elDocumentación de manejo de errores SCSI del kernel de Linux.

4. ¿Por qué se mdsigue utilizando un dispositivo con datos no válidos?

Cuando finalizó el borrado seguro de ATA, la unidad no informó ningún problema, como un comando abortado, por lo que mdno tenía motivos para sospechar que había un problema.

Además, en su caso de utilizar particiones como dispositivos RAID en lugar de discos completos, la tabla de particiones en memoria del kernel no fue informada de que la partición en la unidad borrada había desaparecido, por lo que mdcontinuaría accediendo a usted /dev/sdb1como si nada estuviera mal.

Esto es de lamdpágina de manual:

Depuración y desajustes

Como los dispositivos de almacenamiento pueden desarrollar bloques defectuosos en cualquier momento, es valioso leer periódicamente todos los bloques en todos los dispositivos de una matriz para detectar dichos bloques defectuosos a tiempo. Este proceso se llamadepuración.

Las matrices md se pueden borrar escribiendo:controlarorepararal archivomd/sync_actionen elsistemasdirectorio del dispositivo.

Solicitar una limpieza hará que md lea cada bloque en cada dispositivo de la matriz y verifique que los datos sean consistentes. Para RAID1 y RAID10, esto significa comprobar que las copias sean idénticas. Para RAID4, RAID5, RAID6, esto significa verificar que el bloque de paridad sea (o los bloques sean) correctos.

De esto podemos inferir que la paridad normalmente no se verifica en cada lectura de disco. (Además, verificar la paridad en cada lectura sería muy exigente para el rendimiento al aumentar las transacciones necesarias solo para completar una lectura y ejecutar la comparación de la paridad con los datos leídos).

Bajo operación normal, mdsimplemente asume que los datos que está leyendo son válidos, dejándolo vulnerable acorrupción de datos silenciosa. En su caso, tenía un disco completo de datos corruptos silenciosamente porque lo limpió.

Su sistema de archivos no estaba al tanto de la corrupción. Vio errores de entrada/salida a nivel del sistema de archivos porque el sistema de archivos no podía entender por qué tenía datos incorrectos.

Para evitar la corrupción silenciosa de los datos, primero,nunca vuelvas a hacer lo que hiciste. En segundo lugar, considere usarZFS, un sistema de archivos que se centra en la integridad de los datos y detecta y corrige la corrupción silenciosa de los datos.

información relacionada