Sunday, January 3, 2016

How to block-dump a device in a compressed but stil mountable format

This is the procedure to produce a block-level disk-dump that is both:

  • compressed
  • mountable/runnable with qemu
The procedure is inspired by this post: it uses SquashFS instead of gzip to achieve compression while retaining mountability: the idea is:
  1. build a SquashFS .img file that *contains* the disk-dump .img file
  2. the SquashFS file is compressed by SquashFS itself but can be easily mounted (albeit only read-only)
  3. after the SquashFS file is mounted RO, qemu-img can be used to create a writable qcow2 file based on the raw .img file
  4. the qcow2 file can then be mounted/read/inspected/run as a VM with for example qemu-kvm or qemu-nbd

Dump Procedure:

  • *TURN OFF* the system, I mean *POWER IT OFF* I mean *DON'T JUST SUSPEND/HYBERNATE*, specially if *Windows* 
  • Boot a linux liveCD distro, for example SystemRescue-CD
  • Identify the drive you want to dump, example /dev/sda (you can use fdisk -l or cat /proc/partitions to get some hints)
  • Connect and mount the drive when you want to store the image, for example under /mnt/usb
  • mkdir a new empty directory in /mnt/usb, es 
#mkdir diskdump
  • create the SquashFS image: this command makes a SquashFS by compressing the content of the diskdump directory (empty, or you could add some files of your choice before running this command) and adds to it a virtual file generated on the fly by running dd and dumping your drive
#mksquashfs diskdump /mnt/usb/squash.img -p 'sda.img f 444 root root dd if=/dev/sda bs=4M'
  • this will take a LONG time depending on the CPU power and on the speed of the involved drives. 
  • For me it took around 12h to copy 500GB from an eSATA SSD drive to an USB-2 SATA-5400RPM drive on a dual core i5: total amount written was about 150GB. The 500GB drive contained a dump of a rather filled 250GB partition and was zero-filled to 500GB: the bottleneck seemed to be the target drive (a rather slow external disk on USB2)

Read Procedure:

  • Mount the disk containing your SquashFS .img file, under for example /mnt/usb
  • Now mount *the SquashFS* under for example /mnt/squash
# mount -o ro -t squashfs /mnt/usb/squash.img /mnt/squash
  • If you ls /mnt/squash you should see the file you created in the previous step, so you should see /mnt/squash/sda.img. The size should match the uncompressed size of the disk you dumped
  • If you want to dump it back or copy the .img file itself by just reading it, you can proceed directly. In teory you could losetup a loop device to the .img and mount it directly: but keep in mind the dump file is on a read-only device (the squashfs) and so will only support a read-only mount. If you want to mount the image and browse it, I advice you create a writeble snapshot of it (see below) since many filesystems (NTFS anybody?) don't like a read-only device.

RW Mount Procedure: (writes will be NOT committed to the dump):

  •  Create a temporary writable .qcow2 snapshot of your .img file
#qemu-img create -f qcow2 -o backing_file=/mnt/squash/sda.img,backing_fmt=raw /tmp/writable.qcow2
  • You can now proceed mounting the qcow with for example qemu-nbd
#modprobe nbd max_part=63
#qemu-nbd -c /dev/ndb0 /tmp/writable.qcow2
#fdisk -l /dev/nbd0
  • You can mount any of the listed partitions with the proper filesystem

Umount Procedure:

  • Just remember to umount things in the reverse order
  • Umount all the partitions of /dev/nbd0 you may have mounted
  • Kill nbd
#qemu-nbd -d /dev/nbd0
#killall qemu-nbd
#sleep 5
#killall -9 qemu-nbd
  • Umount the squashfs (mnt/sqashfs)
  • Umount the disk containing the dump (/mnt/usb)
  • Decide if you want to keep writeble.qcow2 or remove it. All the I/O you did to the mounted img file has been written here, NOT in the dump file that is read-only and has not been touched.

No comments:

Post a Comment