Eu acredito que encontrei uma solução para o meu problema. No entanto, ainda estou curioso para saber se alguém pode encontrar uma solução mais elegante ou possivelmente encontrar um erro na minha solução.
Como se constata, eu poderia escrever para stdin de debugfs
, então eu só precisei gerar uma seqüência de comandos para debugfs
, para analisar a saída de ddrescue
.
O seguinte script bash assume que um arquivo chamado mapfile.ddrescue
está presente no diretório atual que foi produzido por ddrescue
.
for line in \
$(cat mapfile.ddrescue | \
grep -e "-$" | \
awk -F" " '{print $1}' | \
awk -F"0x" '{print $2}'); \
do \
position=$(( 16#$line / 512 - 91914240 )); \
result="$result $position"; \
done; \
echo -e "open /dev/sdd3\nicheck $result\nquit\n" | sudo debugfs
Veja o que este script faz:
- Eu analiso o
mapfile
deddrescue
, que eu nomeei demapfile.ddrescue
. - Filtrei para manter apenas as linhas que terminam com um hífen. Essas são as posições com maus blocos.
- Eu uso o awk para dividir no espaço em branco e imprimir o primeiro token que é a posição. Isto irá conter um número hexadecimal como 0x34A933F000.
- eu removo o prefixo
Ox
. - O resultado é retornado pela mão de chamada
$(...)
que serve como entrada para o loop for, portanto, a linha sempre conterá uma posição. - Eu uso a expressão
$(( ... ))
para calcular matemática na posição, dividir a posição por 512 (por exemplo, bytes por setor) e subtrair o início da partição que no meu caso é91914240
. Isto dá uma posição em sektors em relação ao início da partição. - Eu concateno cada posição em uma lista separada por espaços que é armazenada em
$result
. - Finalmente, eu gero uma lista de comandos separada por nova linha, a qual canaliza para stdin do comando
debugfs
que eu executo com sudo. O comando abre o dispositivo (no meu caso/dev/sdd3
). Em seguida, ele executaicheck
no$result
e sai dedebugfs
.
Quando eu executei este script, debugfs
demorou muito tempo para encontrar todos os inodes
para esses blocos, no meu caso, ele ficou pendurado por vários minutos até que imprimisse a saída.
Quando o script foi concluído, copiei o resultado em um arquivo de texto e o analisei. Felizmente, a maioria dos setores apontava para blocos não alocados e os demais apontavam para os mesmos números inode
. Depois de remover linhas com <block not found>
e remover duplicatas, apenas quatro inodes
permaneciam, o que eu podia verificar manualmente com debugfs
usando ncheck
. Isso me deu quatro caminhos de arquivo, esses são os arquivos que eu agora tentarei restaurar de um backup.
Plano de fundo
Eu originalmente comecei com dd
e queria copiar o conteúdo de um SSD de 256GB para um SSD maior. dd
foi anulado com erros de E / S em aproximadamente 45/185 GB da última partição. No entanto, com ddrescue
, economize 99,99% da unidade. Finalmente, com a solução acima, eu fui capaz de verificar em quais arquivos 1700kb ou 418 áreas ruins pertencem e encontrei apenas quatro arquivos que estão quebrados. Isso aumentou bastante minha confiança nos dados restaurados, pois agora sei quais arquivos estão corrompidos e posso restaurá-los de um backup mais antigo.