Mesclar dois arquivos de imagem binária por booleano OR (erro no nome do arquivo de saída do ddrescue)

Mesclar dois arquivos de imagem binária por booleano OR (erro no nome do arquivo de saída do ddrescue)

Cometi um erro bobo ao usar o nome de arquivo de saída errado ao retomar um ddrescue. Isso é o que aconteceu:

ddrescue -b 2048 -d -v /dev/sr1 IDTa.img IDTa.ddrescue.log 

Então o computador travou e eu retomei por engano com:

ddrescue -b 2048 -d -v /dev/sr1 IDTa.iso IDTa.ddrescue.log

Presumo que ambos os arquivos de imagem começarão zerados, então acho que se eu fosse booleano OR ambos os arquivos juntos, o resultado seria o que o ddrescue teria gerado se eu não tivesse cometido o erro?

Os arquivos não são continuações um do outro (comoComo posso mesclar duas imagens ddrescue?) pois já havia executado ddrescue -nanteriormente, que foi concluído com sucesso. ou seja, IDTa.img contém a maioria dos dados, IDTa.iso contém blocos espalhados por toda a imagem (e esses blocos seriam zero em IDTa.img).

Existe uma maneira CLI simples de fazer isso? Eu provavelmente poderia fazer isso em C, mas estou muito enferrujado! Também pode ser um bom primeiro exercício em Python, que nunca aprendi! No entanto, não quero reinventar a roda se algo já existir. Não estou muito preocupado com o desempenho.

Atualizar:(desculpas se este é o lugar errado para responder a uma resposta. A opção 'comentário' parece permitir poucos caracteres, então estou respondendo aqui!)

Eu também tentei o ddrescue com '--fill-mode=?' como solução para o problema acima, mas não funcionou. Isto é o que eu fiz:

ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img IDTa.img.log
cp IDTa.img IDTa.img.backup
ddrescue '--fill-mode=?' -b 2048 -v IDTa.iso IDTa.img IDTa.img.log 

Para verificar, procurei a primeira posição que o IDTa.iso possui dados:

hexdump -C IDTa.iso |less

a saída foi:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
001da800  00 00 01 ba 21 00 79 f3  09 80 10 69 00 00 01 e0  |....!.y....i....|
...
001db000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
...

Procurei 001da800 em IDTa.img:

hexdump -C IDTa.img |less
/001da800

Saída:

001da800  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
001db000  00 00 01 ba 21 00 7b 00  bf 80 10 69 00 00 01 e0  |....!.{....i....|
...

Então, os dados na posição 001da800 não foram copiados do arquivo IDTa.iso para IDTa.img?

Verificando IDTa.img.log:

# Mapfile. Created by GNU ddrescue version 1.22
# Command line: ddrescue --fill-mode=? -b 2048 -v IDTa.iso IDTa.img IDTa.img.log
# Start time:   2021-06-28 13:52:39
# Current time: 2021-06-28 13:52:46
# Finished
# current_pos  current_status  current_pass
0x299F2000     +               1
#      pos        size  status
0x00000000  0x00008000  ?
0x00008000  0x001D2800  +
0x001DA800  0x00000800  ?
0x001DB000  0x00049000  +
...

e uma verificação da realidade:

diff -q IDTa.img IDTa.img.backup

não retorna nenhuma diferença.

Atualização 2:

@Kamil editou a solução (veja abaixo) descartando o --fill-mode=?argumento. Parece funcionar!

Responder1

Acho que isso pode ser feito ddrescuesozinho. Você precisa --generate-mode.

Quando ddrescueé invocado com a opção --generate-modeele opera em "modo de geração", que é diferente do "modo de resgate" padrão. Ou seja, em “modo gerar” ddrescuenão resgata nada. Ele apenas tenta gerar um mapfilepara uso posterior.

[…]

ddrescuepode, em alguns casos, gerar um aproximado mapfile, from infilee a cópia (parcial) in outfile, que é quase tão boa quanto um exato mapfile. Isso é feito simplesmente assumindo que os setores contendo apenas zeros não foram resgatados.

[…]

ddrescue --generate-mode infile outfile mapfile

(fonte)

Faça cópias das duas imagens, por precaução. Se o seu sistema de arquivos suportar cópia CoW, use cp --reflink=alwayspara cada imagem para fazer cópias virtualmente instantaneamente.

Você precisa ter certeza de que as duas imagens têm o mesmo tamanho. Se um deles for menor, então deverá ser ampliado, ou seja, zeros (possivelmente zeros esparsos) deverão ser acrescentados. Este código fará isso automaticamente ( truncateé obrigatório):

( f1=IDTa.img
  f2=IDTa.iso
  s1="$(wc -c <"$f1")"
  s2="$(wc -c <"$f2")"
  if [ "$s2" -gt "$s1" ]; then
    truncate -s "$s2" "$f1"
  else
    truncate -s "$s1" "$f2"
  fi
)

(Eu usei um subshell para que as variáveis ​​morram com ele e o shell principal não seja afetado.)

Agora deixe a ferramenta analisar sua primeira imagem e descobrir quais setores provavelmente não foram resgatados:

ddrescue --generate-mode -b 2048 -v /dev/sr1 IDTa.img new_mapfile

Observe que new_mapfileaqui está um novo arquivo,nãoseu IDTa.ddrescue.log. Não toque IDTa.ddrescue.log.

Após new_mapfileser gerado, as linhas nele deverão mostrar status +ou ?, dependendo se o fragmento correspondente foi considerado "resgatado" ou "não tentado".

Agora você deseja preencher o bloco supostamente "não testado" IDTa.imgcom dados de IDTa.iso. O próximo comando irá modificar o arquivo IDTa.img.

Resgate o bloco supostamente "não testado" IDTa.imglendo dados de IDTa.iso:

ddrescue -b 2048 -v IDTa.iso IDTa.img new_mapfile

Agora o modificado IDTa.imgjunto com o intocado IDTa.ddrescue.logdeve ser tão bom como se você não tivesse cometido o erro.

Notas:

  • Pode ter acontecido que alguns setores contendo apenas zeros foram realmente resgatados. --generate-modeirá classificá-los como ?. Eles serão preenchidos com dados retirados IDTa.iso“em vão”. Isso não importa para o resultado final porque todos eles são zeros neste outro arquivo também.
  • O resultado deverá ser o mesmo se você trocar IDTa.isoe IDTa.imgem todo o procedimento (mas lembre-se que se você fizer isso o resultado estará em IDTa.iso). Então há uma escolha. Com --generate-modeeu usaria o arquivo do qual espero menos setores contendo apenas zeros porque isso deve minimizar a quantidade de trabalho do último comando.
  • O método funciona para arquivos regulares IDTa.isoe IDTa.img. Se, em vez disso, algum deles você tivesse um dispositivo de bloco, seu conteúdo "aleatório" anterior ao seu trabalho ddrescueinterferiria e prejudicaria o resultado (portanto, não faz sentido resolver um problema potencial com tamanhos diferentes em primeiro lugar, onde truncatenão ajuda ).
  • Testei o procedimento depois de replicar seu erro ao tentar resgatar umdispositivo flakey.

informação relacionada