Isso acabou se tornando uma PITA real. Primeiro, é importante notar que o btrfs agora tem um comando de substituição adequado, que é muito melhor do que adicionar novo, remover a falha.
Primeiro, comece particionando o novo disco e configurando o dm-crypt nele. Vá em frente e desbloqueie-o.
Se o seu disco não tiver tempo de gravação (o que significa 360 vezes cada um, aparentemente!), você pode fazer uma simples:
btrfs replace start -r /dev/mapper/luks-BAD-disk-uuid \
/dev/mapper/luks-NEW-disk-uuid /mount/path
No entanto, isso acabará fazendo gravações de rotina no disco defeituoso, e se isso causar um tempo limite, você verá cerca de 30 segundos de cópia rápida, seguidos por 6 a 12 minutos de inatividade, aguardando o tempo limite.
Para evitar gravações, é possível configurar um instantâneo usando o mapeador de dispositivos. As leituras irão para o dispositivo ruim subjacente (que é basicamente OK com leituras); as gravações irão para o armazenamento copy-on-write (COW). Primeiro, você precisa de um dispositivo de bloco adequadamente grande para o armazenamento de COW. Eu criei um novo volume lógico para ele ( Watt-sdj1_dmsnap
). Qualquer dispositivo de bloco deve funcionar - até mesmo um dispositivo de loop deve funcionar bem. Eu pessoalmente sugiro um persistente, apenas no caso de algo dar errado, mas se você estiver vivendo perigosamente e tiver RAM suficiente, um disco RAM funcionaria.
A mina exigiria ~ 1.7GB de espaço em COW (para mover 2.24 TiB de um drive de 3TB). Eu recomendo ser generoso com o espaço de vaca; se esgotar provavelmente seria uma coisa ruim, e você pode liberar tudo quando terminar.
Em seguida, você precisa desmontar o sistema de arquivos btrfs se ele foi montado e bloquear (parar) o dispositivo dm-crypt. Estou colocando o instantâneo abaixo da criptografia porque não quero dados não criptografados gravados no disco.
No meu caso, a partição é /dev/sdj1
. Primeiro, para evitar erros, defina-o como somente leitura:
blockdev --setro /dev/sdj1
blockdev --setro /dev/sdj
(Mais tarde, você pode defini-lo novamente com --setrw
). Agora, realmente configure o instantâneo:
dmsetup create sdj_divert --table "0 $(blockdev --getsz /dev/sdj1) snapshot /dev/sdj1 /dev/mapper/Watt-sdj1_dmsnap PO 8"
Para explicar rapidamente o que isso significa, uma tabela de mapeamento de dispositivo tem o formato: setor de início número de setores tipo de destino argumentos de destino . O setor inicial é 0; o número de setores é o mesmo que o tamanho de sdj1 (afinal, queremos fazer a coisa toda); o tipo de destino é instantâneo. O alvo de snapshots leva vários argumentos: source-dev modo cow-dev chunk-size . Estamos dando um dispositivo de origem de /dev/sdj1
; o dispositivo COW é aquele volume lógico que criei; o modo PO significa p ersistent (os metadados são gravados no disco, portanto, pode ser configurado para backup após uma reinicialização) e o verflow (se gravarmos muito no instantâneo , a recuperação é possível). O tamanho do bloco é o quão granular é o instantâneo; se escrevermos mesmo um byte, o pedaço inteiro em torno desse byte será copiado (e consumirá espaço no instantâneo). 8 é 4K, por isso não haverá problemas de alinhamento.
Agora, finalmente, desbloqueie o dispositivo novamente, mas em vez de desbloquear /dev/sdj1
, desbloqueie /dev/mapper/sdj_divert
. Então vá em frente e monte o sistema de arquivos btrfs novamente.
Você pode verificar o uso do instantâneo com dmsetup status sdj_divert
; que deve dar algo como (mas com um número muito menor antes da barra):
0 5860524928 snapshot 914216/545259520 3568
As três primeiras coisas são o setor inicial, o número de setores e o tipo de destino. O próximo número é o número de setores usados (antes da barra) e, em seguida, o número total de setores (após a barra). Então, isso é uma fração do espaço usado. O número final é o número de setores usados para metadados, que já estão incluídos no número usado.
Agora, finalmente, você pode usar esse simples comando btrfs replace start
na parte superior da resposta. Isso retornará imediatamente; observe o status executando btrfs replace status /mount/path
.
Quando a substituição for concluída, confirme se o dispositivo defeituoso foi removido do sistema de arquivos (por exemplo, btrfs fi show /mount/path
) e, em seguida, você pode bloquear / fechar a unidade com falha e remover a captura instantânea ( dmsetup remove sdj_divert
). Então você pode liberar o espaço COW (depois de limpá-lo, se você estiver paranóico).
Há uma etapa final, tecnicamente opcional: meu dispositivo substituto é maior, mas o btrfs ainda não está usando o espaço extra. Para disponibilizá-lo para o btrfs, procure encontrar o devid na saída btrfs fi show
e, em seguida, execute
btrfs fi resize DEVID:max /mount/path
isso deve ser quase instantâneo.