How to write a sparse Linux (EXT4) disk image without writing gigabytes of zeros?

Solution 1:

dd can handle this. You need to add conv=sparse to the command line.

From the man page:

              try to seek rather than write the output for NUL input blocks

Solution 2:

I would consider using mksquashfs to create a read-only copy instead of making a dd of whole volume. This additionally compresses and de-duplicates the data.

Please note that you have to evaluate - it's usability depends on your specific use case.

Solution 3:

It is awkward since you have a whole disk image but you could:

  1. use your partitioning program of choice to list the partitions in os.img and create them on /dev/sdb
  2. restore each partition with e2image. e.g., e2image -aro 1048576 os.img /dev/sdb1

This does not handle the MBR if there is one. /bin/dd if=os.img of=/dev/sdb bs=512 count=1 will do that.

Note: the e2image man page at linux.die.net is out of date. From a bionic install:

SYNOPSIS
   e2image [ -r|Q ] [ -f ] device image-file
   e2image -I device image-file
   e2image -ra [ -cfnp ] [ -o src_offset ] [ -O dest_offset ] src_fs [ dest_fs ]