Convert a Virtual Machine to Physical
Virtual machines are a great way to test out new software, support legacy applications and more, however for some things a physical machine can't be beaten. Recently I acquired some new hardware and one of the machine I had earmarked as my new spam filtering mail gateway. While searching for a solution I came across a virtual machine called ESVA which is based on CentOS 5.2 and comes ready to run with SpamAssassin, Mailscanner, SQLgrey and more. While testing it out I decided that ESVA was going to be the ideal solution for me. Unfortunately it comes as a virtual appliance only but I figured there must be an easy way to make an image and transfer it to a physical machine. This can be done and is more commonly known as V2P.
Software & Hardware Used
- ESVA Virtual Appliance
- VMware Workstation 5
- Dell Optiplex GX1
Virtual Machine Configuration
- /sda1 mounted as /boot
- /dev/mapper/vg_root-lv_root mounted as /
- /dev/mapper/vg_var-lv_var mounted as /
My first attempt was to use the Clonezilla CD to make an image of the VM and copy it up onto a fileserver and then use it to image the physical machine. However upon imaging the physical machine I ran into problems straight away. By default CentOS prompts you to set up an LVM partition and the ESVA virtual machine was split across two virtual disks. My physical machine only has a single disk and the imaging subsequently failed.
Creating and partitioning a new virtual disk
I decided that it would be possible to copy the data across to a new virtual disk partitioned similarly to the original applicance. With this in mind I added a new IDE disk (the VM originals were SCSI) of 30GB in size and powered up the original ESVA VM and set about partitioning the new virtual disk.
I created three partitions similar to the original:
- /dev/hda1 which was going to be /boot /partition
- /dev/hda2 which was going to be the / partition
- /dev/hda3 which was going to be the /var partition
- /dev/hda4 which was going to be the swap partition.
Clone the existing partitions to the new virtual disk
Once the partitions were created now it was time to copy the data across. This is done relatively easily and quickly with the 'dd' command so first up the /boot partition:
dd if=/dev/sda1 of=/dev/hda1 bs=8M
Next we do the same for the root which on out VM is an LVM partition:
dd if=/dev/mapper/vg_root-lv_root of=/dev/hda2 bs=8M
And finally we do the same for the var partition
dd if=/dev/mapper/vg_var-lv_var of=/dev/hda3 bs=8M
Mount the new partitions and chroot into it
Now our new virtual disk has its data across but we need to alter some settings first so that we can get it to boot. To do this we need to mount our new partitions and chroot into what will be our imaged virtual disk.
While still in the original VM I created a directory /mailserver into which we will mount the partitions on our new virtual disk. It is important to mount the root partition first so we do this as follows:
mount /dev/hda2 /mailserver
Now we can mount the boot partition:
mount /dev/hda2 /mailserver/boot
And finally we can mount our var partition:
mount /dev/hda3 /mailserver/var
You can change into the /mailserver directory and if you list the contents you will see that it is laid out like any other Linux installation.
Before we chroot into the new virtual disk we need to mount the /proc and /dev directories for it to function correctly. So we issue the following commands:
mount -t proc proc /mailserver/proc
mount -o bind /dev /mnt/mailserver/dev
Next we can chroot into the new disk with the following command
chroot /mailserver /bin/bash
In our new chrooted environment we are basically running what will be our new virtual machine on top of the existing one! Everything we do while in the chrooted environment and the programs and commands used will not be from the original virtual machine but from the data we copied across.
Modify essential system files to get our new virtual disk to boot
As the parition layouts on out new virtual disk which will soon become a new virtual machine are different, we will need to edit some essential system files first. Be careful as this is where things may get slightly tricky! The three files we will need to edit are:
So first up we will edit /etc/fstab and change any references of /dev/sda or /dev/mapper to our new partition layout. When you are finished it should look just like this:
/dev/hda2 / ext3 defaults 1 1 /dev/hda3 /var ext3 defaults 1 2 LABEL=/boot /boot ext3 defaults 1 2 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 proc /proc proc defaults 0 0 LABEL=SWAP-hda4 swap swap defaults 0 0
Just as before we will edit /etc/mtab to reflect our new partition layout:
/dev/hda2 / ext3 rw 0 0 proc /proc proc rw 0 0 devpts /dev/pts devpts rw,gid=5,mode=620 0 0 /dev/hda3 /var ext3 rw 0 0 /dev/hda1 /boot ext3 rw 0 0 tmpfs /dev/shm tmpfs rw 0 0 none /var/spool/MailScanner/incoming tmpfs rw 0 0 none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0
It is important that you edit the files yourself and do not copy and paste the two examples here!
Configure the Grub Bootloader
Obviously we want our new virtual machine to be able to boot so we need to configure and install the grub bootloader. First up is to edit /boot/grub/grub.conf to use out new partition layout. When you are done it should look like this:
#boot=/dev/hda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.18-92.1.6.el5vm) root (hd0,0) kernel /vmlinuz-2.6.18-92.1.6.el5vm ro root=/dev/hda2 initrd /initrd-2.6.18-92.1.6.el5vm.img
Just editing grub.conf isn't enough so now we need to install grub. We do this by simply entering 'grub' at the command line to enter grub's command line. So while at the grub> prompt enter the following commands:
If successful you should see somehing similar to this:
Filesystem type is ext3fs, partition type 0xfd
While still at the grub> prompt enter the following:
This will display some results and hopefully among them you should see the following:
Close the grub prompt by entering the command 'quit' and that's it! Our new virtual disk is ready to be added to a new virtual machin in preparation for cloning.
Preparing a new virtual machine
To test your new virtual machine simply create a new basic one. When it has been created, edit it and remove the disk. You need to creeate a new disk and when prompted choose 'Use existing disk' and browse to the virtual disk we prepared above.
Fire up your new virtual machine and if everything is ok it will boot into the ESVA virtual machine just like the original but this time from a single disk. If everything looks okay then you can shutdown the VM and boot it up once again this time from the Clonezilla CD or ISO image.
Using Clonezilla is self explanatory so I will not go into depth about it here but by now you should have used it create your image and used it one more time to transfer the image to your physical machine which hopefully is now up and running.