Crie um arquivo de entrada binário da opção --read-sector do hdparm

3

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 .
por syntaxerror 01.12.2014 / 18:59

1 resposta

1

Supondo que você tenha o GNU sed, você pode tentar ( não realmente testado ):

 hdparm --read-sector $SECTOR /dev/sdb | \
  sed -r -e "0,/succeeded/d" -e 's/(\S\S)(\S\S)//g' | \
  xxd -r -p >> bindata.bin

A chamada sed exclui tudo até a linha succeeded e, em seguida, troca a saída por byte. A chamada xxd -r -p converte o código hexadecimal simples em dados binários.

    
por 03.12.2014 / 09:36