Creating a raw img file of linux system

backupddqemursync

I'm trying to backup a linux system to an IMG file that I can then boot and run in QEMU.

NOTE: I have tested on Lubuntu and tiny core linux.

The process I have followed is:

  • I have 2 hard disks, sda and sdb
  • partition sdb1 and mount sdb1 partition in /mnt/sdb
  • dd an empty file the size of sda to IMG file in the mounted sdb directory. dd if=/dev/zero of=/mnt/sdb/disk.img bs=x count=1 – x being the size of sda
  • I then use fdisk on sda to output the disk layout to a script file and then load that into the disk.img file
  • Then mount it and copy the contents – losetup -P -f disk.img
  • find the loop device

    e.g /dev/loop36 0 0 0 0 /mnt/sdb/disk.img 0 512

  • created the filesystem on the first partition of the loop device – mkfs.ext2 /dev/loop36p1

  • mount the partitioned loop device – mount /dev/loop36p1 /mnt/img
  • then copy the bootsector – dd if=/dev/sda of=disk.img bs=512 count=1 conv=notrunc
  • finally I used rsync to copy over the filesystem to the /mnt/img directory, I've had varying success with this. using:

    $ rsync -aHxv / \
       --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} \
       /mnt/img 
    

I've tried the exact process using Lubuntu as shown above, the rsync command worked however when I try and run the IMG in QEMU it hangs at booting from the hard disk.

When trying the process above in tcl – the rsync command fails and when I try to boot in QEMU it says there is no bootable device.

Does anyone have any advice regarding this? or has done similar things and has a better method to achieve the goal?

Best Answer

  • When copying the boot sector, you also copied the partition table in it. Depending on the versions of fdisk and the exact options used when partitioning both the original sda and the image file, the partition limits may or may not have been exactly in the same places. If they weren't... your loop mounts used the partition offsets your fdisk created, but at boot, the VM would have been using the partition offsets copied from the original sda.

  • You copied the MBR with dd, but the contents of /boot with rsync. The MBR includes block-level offsets to identify the locations of further bootloader components (<filesystem>_stage1.5 or stage2 for GRUB Legacy). It is highly unlikely that these files would have been exactly at the same block locations after a rsync-based copy.

  • You probably missed completely some parts of the bootloader. GRUB Legacy can embed parts of itself to the beginning of a partition, into an area that is outside the filesystem; GRUB2 almost always writes the majority of its core image to the disk blocks just after the MBR, but before the beginning of the first partition. Copying just the 512 first bytes of the disk gets only the traditional MBR, but misses these things. I think this is the most likely reason your boot failed.

Depending on which virtualization method you're planning, you probably should have used mount --bind /dev /mnt/img/dev and likewise for /proc and /sys, then chrooted into the image environment and used its grub-install to properly rewrite the boot loader into the image file with correct block offsets.

Another possible approach would have been to boot the original system in single user mode or otherwise stop as many daemons on the original system as possible (i.e. quiesce the system), and then just dd the whole system disk into an image as a single operation. This way, you'll certainly have to run fsck when booting the resulting image for the first time, but you'd avoid all the complexities with the MBR and bootloaders.

Related Question