0

An external USB flash drive containing 2 partitions is connected to my Raspberry Pi. I want to dd an image file to this external flash drive if the first partition on the flash drive is not the same as the first one of the image file.

To achieve that, I will compare their checksum.

It's easy to compute the checksum of the flash drive's partition : md5sum /dev/sda1

However, how to compute the checksum of the first partition stored in the image file ?

I use Debian 10 operating system.

Kusalananda
  • 333,661

2 Answers2

1
  1. You can use losetup --partscan --find --show /path/to/disk.img to set up one or more loop devices (/dev/loopN) for the image and its partitions

    Example

    dd if=/dev/zero bs=1M count=100 >/tmp/100M.img
    

    pimg() { parted /tmp/100M.img --align optimal unit MiB "$@"; } pimg mklabel gpt pimg mkpart primary 2 50 pimg mkpart primary 51 100%

    pimg print Model: (file) Disk /tmp/100M.img: 100MiB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags:

    Number Start End Size File system Name Flags 1 2.00MiB 50.0MiB 48.0MiB primary 2 51.0MiB 100MiB 49.0MiB primary

    lo=$(losetup --partscan --find --show /tmp/100M.img); echo $lo /dev/loop0

    ls ${lo}* /dev/loop0 /dev/loop0p1 /dev/loop0p2

  2. Rather than generate two checksums, which requires both your existing target and the source image to be read in their entirety, use cmp. This may be more efficient that generating a checksum as it will stop as soon as there is a byte mismatch. (If there is none it will read to the end, but that's no slower than your alternative of using md5sum.)

    cmp /dev/loop0p1 /path/to/existing_image
    

    If you prefer to continue using a tool such as md5sum you can use the loop device we created earlier:

    md5sum /dev/loop0p1
    
  3. Don't use dd - it's at least as quick to use cat or pv, and a lot easier too (no fiddly options to remember that can corrupt data if you get them wrong):

    pv /dev/loop0p1 >/path/to/existing_image
    
Chris Davies
  • 116,213
  • 16
  • 160
  • 287
  • What is the downside of dd ? Everyone seems to use it to burn an image to disk. – fdamien12 Sep 25 '23 at 16:59
  • 1
    "Everyone" just copies everyone else without concrete evidence. I've added a link to an evidential comparison of dd and cat to my answer, @fdamien12 – Chris Davies Sep 25 '23 at 19:27
  • I just realized that the image file is in a zip file and I don't have enough disk space to extract it and then mount it as loop device. Is there a workaround ? – fdamien12 Sep 28 '23 at 09:37
  • @fdamien12. Not easily that I know of. Assuming there's something that will read a ZIP file and output its contents to stdout, you could pull off just the partition table and investigate what block offsets the required partition starts/ends. Then use dd (yes, this time) to extract the relevant blocks from the stream into cmp. Then finally use dd again to copy the relevant blocks to the flash disk. Very complex and I wouldn't really recommend it – Chris Davies Sep 28 '23 at 09:58
1

You can mount the image file as a block device, and then use the md5sum command you show in your question.

Note that all the commands shown below assume you are running as root.

For raw disk images

If it's a raw disk image, you can juse losetup:

losetup -fP --show disk.img

This will allocate a loop device (like /dev/loop0), attach the image, and expose the partitions as device /dev/loop0p1, /dev/loop0p2, etc.

When you're done, losetup -d <device> to disconnect the image.

For qcow2 images

If it's a qcow2 image, you can do something similar using qemu-nbd:

  • Load the nbd kernel module:

    modprobe nbd
    
  • Attach the image to an nbd device. In this command we attach it to /dev/nbd0, but in the unlikely event that is already in use you can specify any available nbd device (there will be 16 by default):

    qemu-nbd -f qcow2 -c /dev/nbd0 disk.qcow4
    
  • Image partitions will be exposed as /dev/nbd0p1, /dev/nbd0p2, etc.

When you're done, run qemu-nbd -d /dev/nbd0 to disconnect the image.

larsks
  • 34,737