Atualmente, estou tentando arduamente resgatar um arquivo muito grande de um HDD que está prestes a morrer (clicando em sons). A falha de leitura é causada apenas por um pequeno par de setores defeituosos .
Como o backup que eu consegui recuperar é muito antigo, meu primeiro plano foi remover o arquivo mesmo com os dados corrompidos. O PhotoRec
acabou por ser a escolha ideal para este trabalho, uma vez que conseguiu recuperar o ficheiro todo . ( testdisk
foi uma falha épica, já que teria simplesmente cortado o arquivo onde o erro foi detectado)
Tendo recuperado o arquivo (parcialmente corrompido) no HDD alvo intacto, os próximos passos a seguir foram:
- use
hdparm --read-sector <device>
e crie arquivos de dados binários a partir de sua saída
- use os dados válidos deles para reparar os (poucos) setores corrompidos usando um editor hexadecimal como
Okteta
.
E, de fato, as rotinas de leitura crua de hdparm
(usei v9.43 ) ( --read-sector
) poderiam ser convencidas a ler os dados da ( alguns) setores defeituosos naquele cilindro errôneo, mas apenas me devolveu um verdadeiro arquivo ascii . Não há nenhuma maneira que eu saiba de diretamente obter a saída para um arquivo binário para executar a segunda etapa descrita acima. Além disso, todas as palavras nos arquivos de saída acabaram sendo byte-swapped (x86-32 aqui no Linux; fixado em v9.45 , cf. esta entrada mais antiga no bug tracker).
Felizmente, existe uma maneira de fazê-lo funcionar mesmo com v9.43 e anterior, usando a opção hdparm
--verbose
, que (na linha incoming_data
) permitirá que os valores hexadecimais sejam obtidos saída exatamente como lida, em ordem de bytes correta
Então é isso que eu criei até agora, para ler 50 setores a partir de 5000:
i=0
while [[ $((i++)) -lt 50 ]]; do
sudo hdparm --verbose --read-sector $((5000+i)) /dev/sdb 2>&1 |
grep 'incoming_data' | cut -f2- -d: | sed 's/^ //' |
tee -a ascdata1_nl
done
tr '\n' ' ' < ascdata1_nl > ascdata1
Ressalva: o primeiro arquivo, ascdata1_nl
, ainda contém caracteres newline . Quando o loop for concluído, depois de transformar as novas linhas em espaços, ascdata1
agora conterá os valores conforme necessário. Agora, byte por byte é gravado em um arquivo .bin:
while read -d ' ' hexbyte; do printf "\x$hexbyte" | tee -a bindata.bin; done < ascdata1
O resultado será um verdadeiro arquivo binário que pode (por exemplo, 'Okteta') ser usado para substituir as áreas (erradas) zeradas no arquivo.
Resposta curta: funciona dessa forma.
Ainda assim, este procedimento parece um pouco complicado demais para mim (?).
Qualquer maneira mais simples de obter um arquivo binário de um dump --read-sector
"hex"?
- Usando
perl
, tenho certeza de que a opção --verbose
em hdparm
pode ser omitida, pois pack()
/ unpack()
fará um ótimo trabalho. (Só não consegui fazer isso com byte pares )
-
dd conv=swab
: Também experimentei essa opção dd
, que infelizmente apenas troca nibbles, transformando a6b8 d6b7
em (inútil) 6a8b 6d7b
.