Introdução
Resumindo em poucas palavras perdi meu volume LVM, fiz várias besteiras na tentativa de recuperá-lo e quando achei que estava tudo perdido, meu amigo
Ariel me deu as ferramentas necessárias para resolver a questão.
As soluções apresentadas aqui não vão se aplicar a qualquer situação de perdas de dados de LVM, mas podem ser a solução se o seu cenário for próximo do meu.
Cenário
Dois discos instalados no notebook
/dev/sda:
/boot - Partição padrão ext4
swap - Partição padrão swap
/ - Partição LVM VG1
/home - Partição LVM VG1
/dev/sdb:
/Dados - Partição LVM VG1
O meu cenário era relativamente simples, um VG compreendendo ambos os discos, sendo que o LV que eu queria recuperar estava isolado no /dev/sdb, aliás, fica a dica: evite quebrar seus LVs em mais de um disco, caso seja possível. Eu acredito que as soluções apresentadas podem funcionar para outros cenários, mas não testei isso! O objetivo aqui é apenas relatar como recuperei o meu cenário.
Criar uma imagem do disco
Esse passo é fundamental, independente de qual solução você escolher, a primeira coisa que você deve fazer é gerar um clone do seu disco.
dd if=/dev/sdX of=/mnt/sdX.img bs=512 conv=noerror,sync
No meu caso:
# dd if=/dev/sdb of=/mnt/sdb.img bs=512 conv=noerror,sync
Onde /mnt é um HD externo, outro disco, uma unidade de rede, enfim, um lugar com espaço suficiente para armazenar uma cópia completa (mesmo tamanho) do seu disco.
Esse processo vai demorar, vai demorar muito... Meu HD de míseros 320 GB demorou mais de 10 horas. Não pule esse passo, se nada funcionar você ainda pode voltar essa cópia para o mesmo disco (ou outro) e envia-lo para uma empresa especializada em recuperação de dados.
Primeira Solução - Montar a imagem do disco de forma direta
Na ordem cronológica do meu caso, essa foi a segunda solução encontrada, mas ela é mais simples, então aconselho você a começar por ela.
Basicamente o que vamos fazer é montar a imagem que temos do disco no sistema e restaurar nossos dados para outro disco.
Essa solução também é um pouco mais limitada: só dá para usá-la caso seu LV esteja alocado em uma faixa contínua no disco, ou seja, se ele tiver apenas um segmento, e estiver situado em apenas um dos discos. Para saber se o seu LV tem apenas um segmento contínuo, veja mais abaixo o dump do metadado feito a partir do início da partição LVM.
# mkdir /Dados2
# mount -o loop,ro,offset=$((2*1024*1024)) /run/media/deo/IMG/Déo/sdb.img /Dados2
O comando mount acima abre um sistema de arquivos contido em uma imagem (arquivo sdb.img), fazendo sua associação a um ponto de montagem. O detalhe importante é a opção offset que ignora os primeiros n bytes do arquivo de imagem. Neste caso foi tentado o valor de 2MB, afim de ignorar o primeiro MB entre o início do disco e a primeira partição e também 1 MB referente ao metadado da partição LVM. Caso você tente usar esse comando, se o mount pedir para você informar o sistema de arquivos, é porque não funcionou, não perca tempo tentando especificá-lo. Dá para tentar também variações como 3*... 4*..., em fim, pode ser que o seu metadado seja maior.
É possivel também que você precise aumentar o offset, caso o LV em questão não esteja no início da partição. Nesse caso some ao valor acima o valor do start_extent multiplicado pelo extent_size, que podem ser encontrados no metadado, discutido mais abaixo.
# ls -las /Dados2
total 23927780
4 drwxr-xr-x. 10 deo deo 4096 Jun 14 17:44 .
4 dr-xr-xr-x. 20 root root 4096 Jun 23 15:29 ..
4 drwx------. 2 deo deo 4096 Mar 24 08:47 centos-6.5-pe-3.7.0-ptb2.13-vbox
8388648 -rw-------. 1 deo deo 8592031744 Jan 4 00:57 CentOS 7 - Zabbix Server.vdi
8388648 -rw-------. 1 deo deo 8592031744 Jan 28 00:13 CentOS Scripts.vdi
# df -kh
Sist. Arq. Tam. Usado Disp. Uso% Montado em
/dev/loop0 294G 93G 186G 34% /Dados2
Segunda Solução - Extrair as informações referentes ao LVM do disco
É isso mesmo que você leu, o LVM guarda uma cópia das configurações dele no início de cada partição integrante do VG, aquele 1MB de metadado do LVM da primeira solução ;-), foi essa solução que salvou a minha pele.
Vamos extrair as primeiras 500 linhas do disco, você pode fazer isso com um live cd por exemplo. Esse arquivo possui os dados que serão a base para recriarmos o nosso volume.
strings -t x /dev/sdX | head -500 > string_dev_sdX.txt
No meu caso:
# strings -t x /dev/sdb | head -500 > string_dev_sdb.txt
Agora você precisa criar um volume LVM na sua máquina, ou instalar o HD que você quer recuperar em uma máquina com LVM funcional. No meu caso eu reinstalei o sistema no /dev/sda criando a mesma estrutura: /boot, swap, / e /home. Como a partição /Dados estava em outro disco, e em somente em um disco, eu não precisei me preocupar muito.
Recapitulando o que temos até agora:
- Sistema funcional com LVM;
- Disco que desejo recuperar instalado na máquina;
- Arquivo que vamos utilizar para recriar os apontamentos.
Carregar o módulo
# modprobe dm-mod
Exibir os volumes físicos:
# pvs -v
Scanning for physical volume names
PV VG Fmt Attr PSize PFree DevSize PV UUID
/dev/sda2 fedora lvm2 a-- 111,59g 0 111,59g 1r10wL-sh0C-KcAF-K9XB-ji2L-hzbM-UBhEDL
/dev/sdb1 lvm2 a-- 298,09g 298,09g 298,09g uYRucm-f2aK-Ye0q-C2Db-QYpg-aw2z-9sBGV3
O que nos interessa é o PV UUID, nesse caso "uYRucm-f2aK-Ye0q-C2Db-QYpg-aw2z-9sBGV3". E o nome do VG funcional, no meu caso "fedora".
Agora é a etapa final, mas antes de mais nada BACKUP:
# cp /etc/lvm/backup/fedora /etc/lvm/backup/fedora_02
# cp /etc/lvm/archive/fedora_00000-427671572.vg /etc/lvm/archive/fedora_2_00000-427671572.vg
Esses arquivos, são os arquivos que o LVM utiliza para controlar quais são os volumes, partições, pontos de montagem e etc.
Ao abrir o arquivo string_dev_sdb.txt, encontramos as informações referentes ao pv1:
102594 pv1 {
10259a id = "uYRucm-f2aK-Ye0q-C2Db-QYpg-aw2z-9sBGV3"
1025c8 device = "/dev/sdb1"
1025de status = ["ALLOCATABLE"]
1025f7 flags = []
102602 dev_size = 625140400
102617 pe_start = 2048
102627 pe_count = 76310
Remova todo esse código hexadecimal, faça as devidas indentações, feche as chaves que estão faltando e, transforme os dados nisso:
pv1 {
id = "uYRucm-f2aK-Ye0q-C2Db-QYpg-aw2z-9sBGV3"
device = "/dev/sdb1"
status = ["ALLOCATABLE"]
flags = []
dev_size = 625140400
pe_start = 2048
pe_count = 76310
}
Agora procure no arquivo string_dev_sdb.txt, as informações referentes ao ponto de montagem dados:
1029b1 dados {
1029b9 id = "SdiIbs-5dcB-hZkU-ykcW-cXy0-EIdr-5DNBwZ"
1029e7 status = ["READ", "WRITE", "VISIBLE"]
102a0d flags = []
102a18 creation_host = "deonote"
102a32 creation_time = 1411552196
102a4d segment_count = 1
102a60 segment1 {
102a6b start_extent = 0
102a7c extent_count = 76310
102a92 type = "striped"
102aa3 stripe_count = 1
102ab5 stripes = [
102ac1 "pv1", 0
Remova todo esse código hexadecimal, faça as devidas indentações, feche as chaves que estão faltando e, transforme os dados nisso:
dados {
id = "SdiIbs-5dcB-hZkU-ykcW-cXy0-EIdr-5DNBwZ"
status = ["READ", "WRITE", "VISIBLE"]
flags = []
creation_host = "localhost"
creation_time = 1411552196
segment_count = 1
segment1 {
start_extent = 0
extent_count = 76310
type = "striped"
stripe_count = 1
stripes = [
"pv1", 0
]
}
}
Essas entradas devem ser inseridas nos dois arquivos:
/etc/lvm/backup/fedora
/etc/lvm/archive/fedora_00000-427671572.vg
MUITA, mas muita atenção na posição em que as informações devem ser inseridas.
Testando a recuperação do volume:
# vgcfgrestore fedora --test -f /etc/lvm/archive/fedora_00000-427671572.vg
TEST MODE: Metadata will NOT be updated and volumes will not be (de)activated.
Restored volume group fedora
Observação:
O meu VG se chama fedora, você deve alterar o comando de acordo com o nome do seu VG. Nenhuma mensagem de erro? Então você fez tudo certinho, caso contrário, reveja suas configurações.
Recuperando o volume:
# vgcfgrestore fedora -f /etc/lvm/archive/fedora_00000-427671572.vg
Restored volume group fedora
Verificando o status do volume:
# lvscan
ACTIVE '/dev/fedora/root' [9,77 GiB] inherit
ACTIVE '/dev/fedora/swap' [512,00 MiB] inherit
ACTIVE '/dev/fedora/home' [101,32 GiB] inherit
inactive '/dev/fedora/dados' [298,09 GiB] inherit
Ativando o volume:
# vgchange -ay
4 logical volume(s) in volume group "fedora" now active
Verificando o status do volume:
# lvscan
ACTIVE '/dev/fedora/root' [9,77 GiB] inherit
ACTIVE '/dev/fedora/swap' [512,00 MiB] inherit
ACTIVE '/dev/fedora/home' [101,32 GiB] inherit
ACTIVE '/dev/fedora/dados' [298,09 GiB] inherit
Montando o volume:
# mkdir /Dados
# mount /dev/fedora/dados /Dados/
Verificando os dados:
# ls -l /Dados/
total 23927780
4 drwxr-xr-x. 10 deo deo 4096 Jun 14 17:44 .
4 dr-xr-xr-x. 20 root root 4096 Jun 23 15:29 ..
4 drwx------. 2 deo deo 4096 Mar 24 08:47 centos-6.5-pe-3.7.0-ptb2.13-vbox
8388648 -rw-------. 1 deo deo 8592031744 Jan 4 00:57 CentOS 7 - Zabbix Server.vdi
8388648 -rw-------. 1 deo deo 8592031744 Jan 28 00:13 CentOS Scripts.vdi
# df -kh
Sist. Arq. Tam. Usado Disp. Uso% Montado em
/dev/mapper/fedora-dados 294G 93G 186G 34% /Dados
Outros cenários
Caso seu problema seja mais complexo, talvez por ter dividido o LV entre os discos, ou então tenha um LV com vários segmentos, decorrente de expansões alternadas de diferentes volumes lógicos, creio que ainda assim seja possível fazer algum procedimento para sua recuperação. Se conseguir fazer o dump do metadado e tiver o conteúdo do disco razoavelmente preservado, o pior que pode acontecer é você ter que calcular o início e final de cada segmento, recortá-los, possívelmente com um dd, especificando valores para skip e count, e juntá-los na ordem correta.
Escrito a 4 mãos pelo mestre Ariel e por esse humilde ser, dono do blog ;-)
Referencias
PissedOffAdmins
ADAMS BROS BLOG
serverfault.com