Bad blocks on LVM, XFS and EXT4 – Parte 1 de 2.

Bom dia a todos,

Na semana passada, no dia em que estava a escrever o meu ultimo post, deparei-me com um erro no syslog centralizado do meu homelab.

O erro em si era referente a um health check a falhar, mostrando o meu vNas de gluster a ficar com um volume offline, e um I/O error num disco de XFS.

Jun 10 21:02:09 vsan2 GlusterFS[1479]: [2015-06-11 01:02:08.385723] M [posix-helpers.c:1464:posix_health_check_thread_proc] 0-storage04-posix: health-check failed, going down
Jun 10 21:02:38 vsan2 GlusterFS[1479]: [2015-06-11 01:02:38.388812] M [posix-helpers.c:1469:posix_health_check_thread_proc] 0-storage04-posix: still alive! -> SIGTERM

Jun 10 21:37:32 vsan2 kernel: [956036.450727] XFS (dm-4): metadata I/O error: block 0x1ffff868 (“xfs_trans_read_buf_map”) error 5 numblks 8
Jun 10 21:37:32 vsan2 kernel: XFS (dm-4): metadata I/O error: block 0x1ffff868 (“xfs_trans_read_buf_map”) error 5 numblks 8

Jun 10 18:04:22 npar1 kernel: [955412.944635] end_request: I/O error, dev sde, sector 1084233832
Jun 10 18:08:00 npar1 kernel: [955631.376876] end_request: I/O error, dev sde, sector 1084233832
Jun 10 18:17:02 npar1 kernel: [956174.334529] end_request: I/O error, dev sde, sector 1084233832
Jun 10 18:39:46 npar1 kernel: [957539.934875] end_request: I/O error, dev sde, sector 1084233832

Nota: A hora da vsan2 está propositadamente com as horas adiantadas de forma a testar comportamentos de skew no gluster. A hora correspondente e real é a indicada pelo virtualizador npar1.

Após investigação descobri que o erro era referente a um bad block num dos discos (uso JBOD’s para sistemas de laboratório não produtivos), que dava o disco virtual a VPS que corria este nó do Gluster.

Este bad block era detetado pelo XFS do brick de guster, que por sua vez era detetado pelo ambiente do gluster e consequentemente colocava o volume offline por inconsistência de dados.

Como resolver? Pelo smartctl do disco, apenas um bad block tinha sido detetado, e o disco tinha acabado de sair de garantia, pelo que não deveria ser algo demasiado grave.

npar1:~ # smartctl -a /dev/sde

smartctl 6.3 2014-07-26 r3976 [x86_64-linux-3.16.7-21-desktop] (SUSE RPM)
Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     SAMSUNG SpinPoint F4 EG (AF)
Device Model:     SAMSUNG HD204UI
Serial Number:    S2H7JD2B400240
LU WWN Device Id: 5 0024e9 004cf4cbb
Firmware Version: 1AQ10001
User Capacity:    2,000,398,934,016 bytes [2.00 TB]
Sector Size:      512 bytes logical/physical
Rotation Rate:    5400 rpm
Form Factor:      3.5 inches
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ATA8-ACS T13/1699-D revision 6
SATA Version is:  SATA 2.6, 3.0 Gb/s
Local Time is:    Fri Jun 12 16:29:46 2015 WEST

SMART support is: Available – device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE

<SNIP>

196 Reallocated_Event_Count 0x0032   252   252   000    Old_age   Always       –       0
197 Current_Pending_Sector  0x0032   100   100   000    Old_age   Always       –       1
198 Offline_Uncorrectable   0x0030   252   252   000    Old_age   Offline      –       0

<SNIP>

SMART Error Log Version: 1
No Errors Logged

Para ter a certeza que o disco estava estável efetuei um dd completo do mesmo diretamente no virtualizador de forma a validar se era apenas realmente um erro que era detetado, ou o inicio de uma avaria mais agressiva.

npar1# dd if=/dev/sde of=/dev/null

Ao fazer este comando, ele passou pelo disco todo e gerou as seguintes mensagens no dmesg:

npar1 kernel: [955412.944611] sd 8:0:1:0: [sde] Unhandled sense code   
npar1 kernel: [955412.944615] sd 8:0:1:0: [sde]      
npar1 kernel: [955412.944635] end_request: I/O error, dev sde, sector 1084233832  
npar1 kernel: [955631.376842] sd 8:0:1:0: [sde] Unhandled sense code   
npar1 kernel: [955631.376848] sd 8:0:1:0: [sde]      

Repeti várias vezes o comando e o resultado foi sempre no mesmo setor:

npar1 kernel: [955631.376876] end_request: I/O error, dev sde, sector 1084233832  
npar1 kernel: [956170.896690] sd 8:0:1:0: [sde] Unhandled sense code   
npar1 kernel: [956170.896692] sd 8:0:1:0: [sde]      
npar1 kernel: [956170.896697] sd 8:0:1:0: [sde]      
npar1 kernel: [956174.334464] sd 8:0:1:0: [sde] Unhandled sense code   
npar1 kernel: [956174.334470] sd 8:0:1:0: [sde]    

<snip>

npar1 kernel: [956174.334529] end_request: I/O error, dev sde, sector 1084233832  
npar1 kernel: [957539.934836] sd 8:0:1:0: [sde] Unhandled sense code   
npar1 kernel: [957539.934863] sd 8:0:1:0: [sde]      
npar1 kernel: [957539.934867] sd 8:0:1:0: [sde] CDB:     
npar1 kernel: [957539.934875] end_request: I/O error, dev sde, sector 1084233832  
npar1 kernel: [963171.737397] sd 8:0:1:0: [sde]      
npar1 kernel: [963171.737401] sd 8:0:1:0: [sde]     

Aparentemente o problema estava fixo apenas a um dos setores do disco. O restante disco estava parcialmente seguro e podia ser usado para testes.

Mas como o fazer? O XFS (recomendado como underlining do brick) não tem o conceito de bad block e como tal não sabe como reagir quando encontra um.
Escolhi então algo que era quase tão rápido, mas já com o conceito de bad block: o filesystem EXT4.

Nota: Todos os discos virtuais passados para dentro de VM’s no meu homelab são derivados de logical volumes de discos físicos para ter uma gestão mais rápida e fácil, maximizando o throughput – sem overhead de duplo filesystem I/O.

/dev/vg_storage_testes_a/vm1 –> disco /dev/sda da VM1
/dev/vg_storage_testes_a/vm1dados –> disco /dev/sdb da VM1

Assim, sem alterar nada na configuração da VM efetuei o backup possível ao conteúdo do storage exportado desde gluster desabilitado, através do seu brick.

Em seguida, e após a desconfiguração do storage e umount do brick, formatei ele com ext4:

 # mkfs.ext4 /dev/vgbricks04/bricks

Imediatamente após e sem efetuar mount ao mesmo corri uma surface scan com o fsck para detetar e adicionar a lista de bad blocks o setor detetado:

# fsck.ext4 -y -c /dev/vgbricks04/bricks

Nota:
-y yes

-c  Check for bad blocks and add them to the badblock list

Como no meu caso o disco virtual era de cerca de 1TB, o processo demorou cerca de 40 minutos. No fim, o fsck indicou que havia atualizado a lista de bad blocks adicionado o novo detetado.

Após a operação, e antes de voltar a restaurar os dados que lá tinha, decidi efetuar mais um stress test ao disco virtual:

# mount -t ext4 /dev/vgbricks04/bricks /bricks/4
# dd if=/dev/zero of=/bricks/4/teste.1

Este comando, gerou um ficheiro de 0’s dentro do filesystem /bricks4/ com o nome teste.1 que é exatamente o que necessitava para validar se existiam erros no novo filesystem construido com a exclusão do badlblock.

Finalmente testei se conseguia ler sem dificuldade o erro (usei o dd_rescue pois mostra os I/O erros que surgem):

 # dd_rescue /bricks/4/teste.1 /dev/null
dd_rescue: (info): Using softbs=128.0kiB, hardbs=4.0kiB
dd_rescue: (warning): Not using sparse writes for non-seekable output
dd_rescue: (info): expect to copy 1073737728.0kiB from /bricks/4/teste.1
dd_rescue: (info): ipos:    382976.0k, opos:    382976.0k, xferd:    1073737728.0k
                   errs:      0, errxfer:         0.0k, succxfer:    1073737728.0k
             +curr.rate:   121900kB/s, avg.rate:   108693kB/s, avg.load: 19.7%
             ………………………………….><   100%  ETA:  0:00

Perfeito. Não se detetou nenhum erro de IO na leitura.
Validando no dmesg do virtualizador por um I/O error. Igualmente nada. Problema ultrapassado.

Foi então altura de repor esse volume de gluster (era apenas um volume local a esse servidor) e efetuar restore desde a vossa ferramenta de backups favorita:

# gluster volume create storage04 transport tcp vsan2:/bricks/4/data/
# gluster volume start storage04

Como conclusão, a solução que apresento acima é extremamente útil para os bad blocks que vão aparecendo em discos externos que tanto são usados para homelabs, e que devido a sua mobilidade vão sofrendo erros de superfice.

Não recomendo que este discos com este tipo de erros sejam usados em produção.

Todos os fabricantes de discos, incluem em espaço invisível para o utilizador final, uma percentagem de setores de disco para reserva e realocação em caso de bad blocks.
Se o disco não conseguiu o realocar (como foi o caso), podem existir já muitos mais setores danificados e este pode ser apenas o primeiro a ser notado. Fica o aviso e o alerta.

Caso tenham duvidas, ou sugestões estão sempre convidados a entrar em contacto comigo através do email nuno at nuneshiggs.com

Abr.
Nuno