When cloning disks for device manufacturing, we often encounter storage inefficiency when using standard dd
commands. The traditional approach:
dd if=/dev/sda of=master_image.img
creates an exact byte-for-byte copy including all unused space, resulting in unnecessarily large image files.
From the fdisk -l
output, we can see:
Disk /dev/sda: 64.0 GB (64023257088 bytes)
Partition table shows only about 4GB used space
MBR and partition structure must be preserved
Here's the most efficient method to create a bootable image without empty space:
# Calculate total used blocks
BLOCKS=$(blockdev --getsize64 /dev/sda)
BLOCK_SIZE=512
# Create image with only used blocks
dd if=/dev/sda of=compact_image.img bs=$BLOCK_SIZE count=$(($BLOCKS/$BLOCK_SIZE)) conv=sparse
For more advanced control over what gets copied:
# Install partclone if needed
sudo apt-get install partclone
# Create image preserving boot sector
partclone.extfs -c -s /dev/sda -o compressed_image.img
Always verify your image before deployment:
# Check MBR preservation
fdisk -l compact_image.img
# Verify boot capability
qemu-system-x86_64 -hda compact_image.img
For manufacturing environments, consider this automated script:
#!/bin/bash
DISK="/dev/sda"
OUTPUT_FILE="/mnt/fileserver/device_$(date +%Y%m%d).img"
# Calculate optimal block size
BLOCK_SIZE=$(blockdev --getbsz $DISK)
TOTAL_BLOCKS=$(blockdev --getsize $DISK)
# Create sparse image
echo "Creating optimized disk image..."
dd if=$DISK of=$OUTPUT_FILE bs=$BLOCK_SIZE count=$TOTAL_BLOCKS conv=sparse,notrunc
# Verify checksum
echo "Verifying image..."
md5sum $DISK > ${OUTPUT_FILE}.md5
md5sum -c ${OUTPUT_FILE}.md5
When creating disk images for device manufacturing, we often face storage inefficiency when using traditional dd
commands. The challenge is to create a compact image that:
- Preserves the Master Boot Record (MBR)
- Maintains partition structure
- Only includes allocated blocks (excluding empty space)
- Remains bootable after restoration
The best approach combines dd
with sparse file creation and proper partition handling:
# Create a sparse image file
dd if=/dev/sda of=disk.img bs=4M conv=sparse
# Alternatively, for more control over sparse allocation
fallocate -l $(blockdev --getsize64 /dev/sda) disk.img
truncate -s $(blockdev --getsize64 /dev/sda) disk.img
For better efficiency when dealing with specific partitions:
# Get partition information
sfdisk -d /dev/sda > partitions.sfdisk
# Create image for each partition
for part in /dev/sda*; do
partnum=${part##*sda}
[ "$partnum" = "" ] && continue # Skip the whole disk device
# Get partition size in bytes
size=$(blockdev --getsize64 "$part")
# Create sparse image
dd if="$part" of="part${partnum}.img" bs=4M conv=sparse count=$((size/4096))
done
For ext2/3/4 filesystems, we can optimize further:
# Create compressed image of used blocks only
for part in /dev/sda*; do
case $(blkid -o value -s TYPE "$part") in
ext2|ext3|ext4)
e2image -ra -p "$part" "part-$(basename "$part").img"
;;
*)
dd if="$part" of="part-$(basename "$part").img" bs=4M conv=sparse
;;
esac
done
To restore the image to a new device:
# Restore MBR and partition table
dd if=disk.img of=/dev/sdb bs=446 count=1
sfdisk /dev/sdb < partitions.sfdisk
# Restore partitions
for img in part*.img; do
partnum=${img//[^0-9]/}
dd if="$img" of="/dev/sdb${partnum}" bs=4M
done
Always verify your images:
# Check filesystem integrity
fsck -n /dev/sdb1
# Verify boot capability
file -s /dev/sdb1 | grep -q 'boot sector' && echo "Bootable" || echo "Not bootable"
# Compare checksums
cmp /dev/sda1 /dev/sdb1