(M)  s i s t e m a   o p e r a c i o n a l   m a g n u x   l i n u x ~/ · documentação · suporte · sobre

  Página seguinte Página anterior Índice

606. Recuperando os blocos de dados

Esta parte pode ser tanto mais fácil quanto mais difícil. Depende se o arquivo que se está tentando recuperar tenha ou não mais de 12 blocos de tamanho.

606.1 Arquivos curtos

Se o arquivo não tinha mais que 12 blocos de tamanho, então os números dos blocos de todos os seus dados estão armazenados no inode: pode-se lê-los diretamente da saída stat do inode. Além disso, debugfs tem um comando que desempenha esta tarefa automaticamente. Para exemplificar o que tivemos antes, repetimos aqui:

debugfs:  stat <148003>
Inode: 148003   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
User:   503   Group:   100   Size: 6065
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 12
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
594810 594811 594814 594815 594816 594817 
TOTAL: 6

Este arquivo tem seis blocos (veja o campo BLOCKS). Uma vez que ele é menor que o limite de 12, usaremos debugfs para escrever o arquivo em um novo local, chamando-o de /mnt/recuperado.000:

debugfs:  dump <148003> /mnt/recuperado.000

Naturalmente que isto também pode ser feito com fsgrab, no seguinte formato:

# fsgrab -c 2 -s 594810 /dev/hda5 > /mnt/recuperado.000
# fsgrab -c 4 -s 594814 /dev/hda5 >> /mnt/recuperado.000

Tanto com debugfs ou fsgrab, haverá algum lixo no final de /mnt/recuperado.000, porém isso não é importante. Caso se queira livrar-se dele, o método mais simples é verificar o campo Size do inode e utilizá-lo na opção bs em uma linha de comando dd:

# dd count=1 if=/mnt/recuperado.000 of=/mnt/resized.000 bs=6065

Claro que é possível que um ou mais dos blocos que compunham o arquivo tenham sido sobrescritos. Se isso aconteceu, então você está sem sorte pois o bloco se foi para sempre (mas só pense se você tivesse desmontado mais cedo!).

606.2 Arquivos maiores

Os problemas crescem quando o arquivo tem mais de 12 blocos de dados. Vale a pena saber um pouco sobre a estruturação do sistema de arquivos UNIX. Os dados do arquivo são armazenados em unidades chamadas 'blocos'. Estes blocos podem ser numerados seqüencialmente. Um arquivo também tem um 'inode', que é o lugar onde são guardadas informações como quem é o proprietário, quais as permissões, e qual o tipo do arquivo. Como os blocos, os inodes são numerados seqüencialmente, embora tenham uma seqüência diferente. Uma entrada de diretório consiste do nome do arquivo e um número de inode.

Mas com este estado de coisas, é ainda impossível para o kernel encontrar os dados correspondentes a uma entrada de diretório. Por isso o inode também armazena o local dos blocos de dados, como se segue:

  • Os números dos blocos dos primeiros 12 blocos de dados estão armazenados diretamente no inode. Estes às vezes são chamados de blocos diretos .
  • O inode contém o número do bloco de um bloco indireto. Um bloco indireto contém os números de blocos de 256 blocos de dados adicionais.
  • O inode contém o número do bloco de um bloco duplamente indireto. Um bloco duplamente indireto contém os números de blocos de 256 blocos indiretos adicionais.
  • O inode contém o número do bloco de um bloco três vezes indireto. Um bloco três vezes indireto contém os números de blocos de 256 blocos duplamente indiretos adicionais.

Leia novamente: sei que é complexo, mas também é importante.

Agora, a implementação do kernel atual (certamente para todas as versões acima de 2.0.30) infelizmente zera todos os blocos indiretos (e os blocos duplamente indiretos, e assim por diante) quando apaga um arquivo. Assim se seu arquivo for maior que 12 blocos, não se tem garantia de poder encontrar até mesmo os números de todos os blocos que se precisa, isso sem mencionar os seus conteúdos.

O único método que eu pude encontrar até aqui é presumir que o arquivo não foi fragmentado: se foi, temos problemas. Supondo que o arquivo não foi fragmentado, há vários planos de blocos de dados de acordo com quantos blocos de dados o arquivo usou:

0 to 12

Os números dos blocos estão guardados no inode como descrito acima.

13 to 268

Depois dos blocos diretos, conte um para o bloco indireto, e então existem 256 blocos de dados.

269 to 65804

Como antes, há 12 blocos diretos, um (inútil) bloco indireto, e 256 blocos. Estes são seguidos por um duplamente (inútil) bloco indireto, e 256 repetições de um (inútil) bloco indireto e 256 blocos de dados.

65805 ou mais

O plano dos primeiros 65804 blocos é como acima. Então segue três vezes um bloco indireto e 256 repetições de uma `seqüência duplamente indireta'. Cada seqüência duplamente indireta consiste de um bloco duplamente indireto, seguido por 256 repetições de um (inútil) bloco indireto e 256 blocos de dados.

Claro, mesmo se estes números de blocos de dados presumidos estiverem corretos, não há garantia de que seus dados estejam intactos. Além disso, quanto mais longo for arquivo, menor a chance de que tenha sido escrito no sistema de arquivos sem a fragmentação apreciável (exceto em circunstâncias especiais).

Note que presumo do começo ao fim que o tamanho de bloco é de 1024 bytes, por ser este o valor padrão. Caso os blocos sejam maiores, alguns dos números acima mudarão. Especificamente: uma vez que cada número de bloco tem 4 bytes de comprimento, um tamanho de bloco/4 é o valor do número de blocos que podem ser armazenados em cada bloco indireto. Assim todas as vezes que o número 256 aparecer na discussão acima, substitua-o pelo tamanho de bloco/4. Os limites de 'números de blocos necessários' também terão que ser mudados.

Vamos dar uma olhada num exemplo de recuperação de um arquivo mais longo.

debugfs:  stat <1387>
Inode: 148004   Type: regular    Mode:  0644   Flags: 0x0   Version: 1
Usuário:   503   Group:   100   Size: 1851347
File ACL: 0    Directory ACL: 0
Links: 0   Blockcount: 3616
Fragment:  Address: 0    Number: 0    Size: 0
ctime: 0x31a9a574 -- Mon May 27 13:52:04 1996
atime: 0x31a21dd1 -- Tue May 21 20:47:29 1996
mtime: 0x313bf4d7 -- Tue Mar  5 08:01:27 1996
dtime: 0x31a9a574 -- Mon May 27 13:52:04 1996
BLOCKS:
8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8583
TOTAL: 14

Parece haver um chance razoável de que este arquivo não seja fragmentado: certamente os primeiros 12 blocos listados no inode (que são todos blocos de dados) são adjacentes. Portanto podemos começar salvando aqueles blocos.

# fsgrab -c 12 -s 8314 /dev/hda5 > /mnt/recuperado.001

Agora, o próximo bloco listado no inode, o 8326, é um bloco indireto que podemos ignorar. Mas confiamos que ele será seguido por 256 blocos de dados (dos números 8327 até 8582).

# fsgrab -c 256 -s 8327 /dev/hda5 >> /mnt/recuperado.001

O bloco final listado no inode é 8583. Note que vamos bem em termos do arquivo ser adjacente: os últimos dados que escrevemos foram do bloco número 8582, que é 8327 + 255. Este bloco 8583 é duplamente indireto, o qual pode ser ignorado. É seguido por até 256 repetições de um bloco indireto (que é ignorado) seguido por 256 blocos de dados. Usando a aritmética rapidamente, nós emitimos os seguintes comandos. Note que pulamos o bloco duplamente indireto número 8583, e o bloco indireto 8584 imediatamente (esperamos) a seguir, e começamos no bloco 8585 para dados.

# fsgrab -c 256 -s 8585 /dev/hda5 >> /mnt/recuperado.001
# fsgrab -c 256 -s 8842 /dev/hda5 >> /mnt/recuperado.001
# fsgrab -c 256 -s 9099 /dev/hda5 >> /mnt/recuperado.001
# fsgrab -c 256 -s 9356 /dev/hda5 >> /mnt/recuperado.001
# fsgrab -c 256 -s 9613 /dev/hda5 >> /mnt/recuperado.001
# fsgrab -c 256 -s 9870 /dev/hda5 >> /mnt/recuperado.001

Somando, nós vemos que até aqui escrevemos 12 + (7 * 256) blocos, o que são 1804. O resultado do `stat' para o inode nos deu um 'contador de blocos' de 3616; infelizmente estes blocos tem 512 bytes de comprimento (como uma ressaca do UNIX), assim nós realmente queremos 3616/2 = 1808 blocos de 1024 bytes. Isto significa que precisamos só de mais quatro blocos. O último bloco de dados escrito foi o número 10125. Como estivemos fazendo até aqui, omitimos um bloco indireto (número 10126) e podemos escrever então aqueles últimos quatro blocos.

# fsgrab -c 4 -s 10127 /dev/hda5 >> /mnt/recuperado.001

Agora, com um pouco de sorte, todo o arquivo foi recuperado com sucesso. Ufa!!


Página seguinte Página anterior Índice