Fusionar dos archivos de imagen binarios mediante OR booleano (error en el nombre del archivo de salida de ddrescue)

Fusionar dos archivos de imagen binarios mediante OR booleano (error en el nombre del archivo de salida de ddrescue)

Cometí un error tonto al usar el nombre de archivo de salida incorrecto al reanudar un ddrescue. Esto es lo que pasó:

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

Luego la computadora falló y por error continué con:

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

Supongo que ambos archivos de imagen comenzarán todos en cero, así que supongo que si tuviera que usar el valor booleano O ambos archivos juntos, el resultado sería lo que habría generado ddrescue si no hubiera cometido el error.

Los archivos no son continuaciones uno del otro (como¿Cómo puedo fusionar dos imágenes ddrescue?) ya que ya lo había ejecutado ddrescue -nanteriormente, y se completó con éxito. es decir, IDTa.img contiene la mayoría de los datos, IDTa.iso contiene bloques dispersos por toda la imagen (y esos bloques serían cero en IDTa.img).

¿Existe una forma CLI sencilla de hacer esto? Probablemente podría hacer esto en C, ¡pero estoy muy oxidado! ¡También podría ser un buen primer ejercicio en Python, que nunca he podido aprender! Sin embargo, no quiero reinventar la rueda si ya existe algo. No se preocupa demasiado por el rendimiento.

Actualizar:(Disculpas si este es el lugar equivocado para responder a una respuesta. La opción 'comentario' parece permitir muy pocos caracteres, ¡así que responderé aquí!)

También probé ddrescue con '--fill-mode=?' como solución a lo anterior, pero no funcionó. Esto es lo que hice:

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 comprobarlo, busqué la primera posición en la que IDTa.iso tiene datos:

hexdump -C IDTa.iso |less

el resultado fue:

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  |................|
*
...

Busqué 001da800 en IDTa.img:

hexdump -C IDTa.img |less
/001da800

Producción:

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....|
...

Entonces, ¿los datos en la posición 001da800 no se han copiado del archivo IDTa.iso a IDTa.img?

Comprobando 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  +
...

y una revisión de la realidad:

diff -q IDTa.img IDTa.img.backup

no devuelve ninguna diferencia.

Actualización 2:

@Kamil editó la solución (ver más abajo) eliminando el --fill-mode=?argumento. ¡Parece funcionar!

Respuesta1

Creo que esto se puede hacer por ddrescuesí solo. Necesitas --generate-mode.

Cuando ddrescuese invoca con la opción, --generate-modeopera en "modo generar", que es diferente del "modo rescate" predeterminado. Es decir, en "modo generar" ddrescueno rescata nada. Solo intenta generar un mapfilepara uso posterior.

[…]

ddrescueEn algunos casos, puede generar una copia aproximada mapfilede infiley (parcial) en outfile, que es casi tan buena como una exacta mapfile. Lo hace simplemente asumiendo que los sectores que contienen todos ceros no fueron rescatados.

[…]

ddrescue --generate-mode infile outfile mapfile

(fuente)

Haz copias de las dos imágenes, por si acaso. Si su sistema de archivos admite copia CoW, utilícelo cp --reflink=alwayspara cada imagen para realizar copias prácticamente al instante.

Debes asegurarte de que las dos imágenes tengan el mismo tamaño. Si uno de ellos es más pequeño, entonces se debe ampliar, es decir, se deben agregar ceros (posiblemente ceros escasos). Este código hará esto automáticamente ( truncatees obligatorio):

( 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
)

(Usé un subshell para que las variables desaparezcan con él y el shell principal no se vea afectado).

Ahora deja que la herramienta analice tu primera imagen y descubra qué sectores probablemente no fueron rescatados:

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

Tenga en cuenta que new_mapfileaquí hay un archivo nuevo,nosu IDTa.ddrescue.log. No tocar IDTa.ddrescue.log.

Una vez new_mapfilegenerado, las líneas deben mostrar el estado +o ?, dependiendo de si el fragmento correspondiente se consideró "rescatado" o "no probado".

Ahora desea completar el bloque supuestamente "no probado" IDTa.imgcon datos de IDTa.iso. El siguiente comando modificará IDTa.img.

Rescate el bloque supuestamente "no probado" IDTa.imgleyendo datos de IDTa.iso:

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

Ahora lo modificado IDTa.imgjunto con lo intacto IDTa.ddrescue.logdebería ser tan bueno como si no hubieras cometido el error.

Notas:

  • Puede haber sucedido que algunos sectores que contenían todos ceros fueron realmente rescatados. --generate-modelos clasificaremos como ?. Se llenarán con datos extraídos de IDTa.iso"en vano". Esto no importa para el resultado final porque todos son ceros en este otro archivo también.
  • El resultado debería ser el mismo si intercambias IDTa.isoy IDTa.imgen todo el procedimiento (pero ten en cuenta que si haces esto, el resultado estará en IDTa.iso). Entonces hay una opción. Con --generate-modeusaría el archivo del que espero menos sectores que contengan todos ceros porque esto debería minimizar la cantidad de trabajo para el último comando.
  • El método funciona para archivos normales IDTa.isoy IDTa.img. Si en lugar de alguno de ellos tuvieras un dispositivo de bloqueo, su contenido "aleatorio" anterior a tu trabajo ddrescueinterferiría y estropearía el resultado (por lo que no tiene sentido resolver un problema potencial con diferentes tamaños en primer lugar, lo que truncateno ayuda ).
  • Probé el procedimiento después de replicar tu error al intentar rescatar a undispositivo escamoso.

información relacionada