Working with Disk and Partition images

Once you have got you system set up just the way you want it you should take a backup, that way if anything goes wrong all your hard work won’t be wasted. Actually you should take at least two backups.

If you use Linux the method shown here will work with almost any system, providing you can boot from a live CD, but it is even easier to use if you have a Raspberry Pi since the SD card can be simply removed and inserted into your PC. However, whether or not you use this method on a PC or a Raspberry Pi do not attempt to create a backup image of a partition without unmounting it first.

Creating a Disk or Partition Image

To minimise the size of the backup file it is a good idea to overwrite all the unused space on the device or partition with nulls before backing it up. The following commands mount each of the partitions typically found on a Raspberry Pi SD card in turn, and overwrites all the free space with nulls. Given that an SD card can only be written to so many time before it fails you may want to skip this step, however overwriting any unused space will allow the unused space to be compressed effectively.

# mount /dev/sdb1 /mnt
# dd if=/dev/zero of=/mnt/nul bs=512;sync;sync;sync;rm /mnt/nul;sync
# umount /dev/sdb1
# mount /dev/sdb2 /mnt
# dd if=/dev/zero of=/mnt/nul bs=512;sync;sync;sync;rm /mnt/nul;sync
# umount /dev/sdb2

Then copy the contents of each partition (or the whole disk) to an image file, piping the output through gzip to compress it on the fly as it is created. The ampersand at the end of the command will cause the process to run in the background, allowing you to monitor its progress.

# dd if=/dev/sdb1 bs=512 | gzip -9 -c > ./sdb1.img.gz &
# dd if=/dev/sdb2 bs=512 | gzip -9 -c > ./sdb2.img.gz &

OR

# dd if=/dev/sdb bs=512 | gzip -9 -c > ./sdb.img.gz &

To see how the backup is progressing you need to determine the ID of the process.

# ps -a |grep dd
1854 pts/0 00:00:04 dd

Having found the process ID you can monitor the progress of the backup by sending it a user signal using kill. The other commands just ensure the output from the background process doesn’t interfere with the command prompt, but they are not really necessary.

Note – I’ve found that on some architectures a user signal causes the process to exit, unfortunately this means that you can’t monitor the progress of the backup and just have to be (very) patient.

# echo;kill -usr1 1854;sleep 1;echo

14714753+0 records in 14714753+0 records out
7533953536 bytes (7.5 GB) copied, 151.123 s, 49.9 MB/s

When the backup is finished the process will print a summary and exit.

67108865+0 records in
67108865+0 records out
34359738880 bytes (34 GB) copied, 700.619 s, 49.0 MB/s
[1]+ Done dd if=/dev/sdb bs=512 | gzip -c > /mnt/sdb.img.gz


It is a good idea to check that gunzip can read the image file (using the test option)..

# ls sdb.img.gz -alh
-rwxr-xr-x 1 root root 32M Jan 27 15:46 sdb.img.gz
# gunzip -t /mnt/sdb.img.gz


Mounting a Disk or Partition Image

If you want to access an individual file in you backup image, or even if you want to make a change to a configuration file, you don't have to restore the image, you can mount it directly using the loopback option. To do this you may need to be running as root.

$ su
Password: 

OR

$ sudo -i
Password: 


Mounting an individual partition image is relatively easy (though you need to decompress it first).

# gunzip sdb2.img.gz
# ls sdb3.img
sdb3.img
# mount -o loop sdb2.img /mnt
# ls /mnt/home
pi
#

However if you want to mount an individual partition in a disk image you need to work out what the offset to the start of the partition from the beginning of the file is first. Fortunately you can do this in exactly the same way as you would if the disk image was a real disk.

# fdisk -lu sdb.img
Disk sdb.img: 0 MB, 0 bytes 4 heads, 32 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x000ee283

Device Boot Start End Blocks Id System
sdb1 * 2048 133120 65536+ b W95 FAT32
Partition 1 has different physical/logical endings:
phys=(1023, 3, 32) logical=(1040, 0, 1)
sdb2 133121 4096000 1981440 83 Linux
Partition 2 has different physical/logical endings:
phys=(1023, 3, 32) logical=(32000, 0, 1)

In this case sdb2 starts 133121 sectors from the beginning of the disk, so we need to calculate the offset in bytes and then use this information to mount the sdb2.

# echo $((133121 * 512))
68157952
# mount -o loop,offset=68157952 sdb.img /mnt
# ls /mnt/home
pi


Restore a Disk or Partition image

To restore a backup image.

# gunzip -c /mnt/sdb2.img.gz | dd of=/dev/sdb2 bs=512 &

OR

# gunzip -c /mnt/sdb.img.gz | dd of=/dev/sdb bs=512 &

When the backup is finished the process will print a summary and exit.

67108865+0 records in
67108865+0 records out
34359738880 bytes (34 GB) copied, 604.882 s, 56.8 MB/s
[1]+ Done gunzip -c /mnt/sdb.img.gz | dd of=/dev/sdb bs=512


Raspberry Pi is a trademark of the Raspberry Pi Foundation

This entry was posted in Linux. Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s