Wednesday 14 April 2010

Cloning a Linux distro inside a VirtualBox VM to a real machine

Recently I tried out LinuxMint Helena LXDE inside a VirtualBox virtual machine. Very nice it was too. I decided that I wanted it installed on a real machine. Being loath to do another install on the real machine I decided to do a network clone, a technique that I have refined over time.


The key idea is to boot both machines with a rescue CD and mount their respective disks. I use SystemRescueCD because it's very up to date with all kinds of filesystems and modules. Then we create a network pipe with netcat and tar the source machine filesystem onto the target machine. I won't specify every step in detail; you have to fill in some details yourself.


First boot the source machine and make a note of the partition filesystems and sizes. In the case of LinuxMint LXDE, it's one of the standard Ubuntu setups, / in /dev/sda1 and an extended partition /dev/sda2 containing a swap in /dev/sda5. I noted the size of the swap, and that / was ext4.


Then boot the target machine. First setup the networking and note the address assigned to the network interface. Then using fdisk, create the same layout. However you can make the disk larger or smaller, so keep the swap partition the same size (I assume your VM was created with the same amount of memory as your real machine; otherwise use the 2xRAM rule) but adjust /dev/sda1 to suit. This is one advantage of this cloning method, you can increase the size of the disk. Then create the target filesystems:


mkfs.ext4 /dev/sda1
mkswap /dev/sda5


Now on both systems, mount the root filesystem and any other filesystems on it. We have only / so this will do:



mkdir /disk; mount /dev/sda1 /disk



Go to the top of the target filesystem and start a netcat listener piping into tar:



cd /disk; netcat -l 2222 | tar zxvf -



On the source machine, mount the source filesystem.



mkdir /disk; mount /dev/sda1 /disk



Go to the top of the source filesystem and start a tar feeding into netcat:



cd /disk; tar zcvf - * | netcat 192.168.1.123 2222



Subsitute the real IP address for 192.168.1.123 above. You will see the files being packed up and sent over. On the target machine you will see the files extracting.


Netcat doesn't terminate at end of input so you have to judge when there are no more files to be tar'red and interrupt it. Usually it's the last file alphabetically, something like /var/xxx or /vmlinuz, depending.


Now you have to reinstall GRUB on the target machine. LinuxMint Helena uses GRUB2, so



grub2-install --root-directory=/disk /dev/sda



You also have to adjust the UUIDs of the partitions or it will not boot. Look at the UUIDs in /disk/etc/fstab, then use tune2fs and mkswap to fix:



tune2fs -U xxxx-xxxx /dev/sda1
mkswap -U yyyy-yyyy /dev/sda5



where the xxxx-xxxx and yyyy-yyyy are the long UUIDs. I recommend cut and paste from /disk/etc/fstab to avoid keying errors.


Another thing you might want to fix up is the label of the ethernet interface. Edit /etc/udev/rules.d/70-persistent-net.rules and comment out the entry for eth0 which will be for a pcnet32, the default "hardware" for VirtualBox VMs and promote the eth1 entry to eth0. This is cosmetic since the system will work fine with eth1 as the network interface.


Other distros may require more fixing up of sound or video configuration. Fortunately LinuxMint (and Ubuntu distros in general) work out these things and adapt more or less automatically.


Now you should be able to boot the target machine. Have fun.


It is also possible to do the reverse, but as the VM is inside a private network, you have to use bridging, or ssh forwarding to pipe the tar stream into the VM. This is one way to virtualise a real install.

No comments:

Post a Comment