[kwlug-disc] Converting a running Linux box to a Virtual Machine

Chris Frey cdfrey at foursquare.net
Sat May 15 00:20:19 EDT 2010


On Fri, May 14, 2010 at 10:42:14PM -0400, Khalid Baheyeldin wrote:
> Which virtualization technology did you use for this (VMWare, Xen,
> VirtualBox, other)?

I use QEMU, but that's mostly because I don't have the modern
VM-capable CPU, and I don't want to run closed source VMWare, which in the
past conflicted with my kernels.


> What are the steps to convert a running bare metal Linux installation to a
> virtual machine?

See the bird's-eye view summary in my response to unsolicited.  Maybe I
should write something up with actual commands, though.

I'm sure there's gotta be a script out there that does this, but
it's nice to know the low level commands too:

Ok... here it is.  These steps take you through the low level steps of
creating a disk.  After that, it should be pretty straightforward.


Note, you don't have to be root for most of these steps.


1) Decide how big you want your disk.  Let's assume 40gigs.

2) Create your sparse disk file

	dd if=/dev/zero of=disk.img count=1 seek=40000000000 bs=1

3) Partition it

	/sbin/fdisk -u ./disk.img

Example:
==============================================================================
# /sbin/fdisk -u ./disk.img 
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x6cf5f055.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

You must set cylinders.
You can do this from the extra functions menu.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): p

Disk ./disk.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x6cf5f055

     Device Boot      Start         End      Blocks   Id  System

===============================================================================

5) Calculate the number of cylinders

	40000000000 / 255 / 63 / 512 = 4863 cylinders

6) Set the cylinders to make fdisk happy

===============================================================================
Command (m for help): x

Expert command (m for help): c
Number of cylinders (1-1048576): 4863

The number of cylinders for this disk is set to 4863.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Expert command (m for help): r

Command (m for help): p

Disk ./disk.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 4863 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x6cf5f055

     Device Boot      Start         End      Blocks   Id  System

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First sector (63-78124094, default 63): 
Using default value 63
Last sector or +size or +sizeM or +sizeK (63-78124094, default 78124094): 
Using default value 78124094

Command (m for help): p

Disk ./disk.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 4863 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes
Disk identifier: 0x6cf5f055

     Device Boot      Start         End      Blocks   Id  System
./disk.img1              63    78124094    39062016   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 25: Inappropriate ioctl for device.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.

===============================================================================

7) Calculate the size of your partition

	78124094 - 62 = 78124032 sectors
	78124032 * 512 = 39999504384 bytes

8) Create your filesystem

	dd if=/dev/zero of=fs.img count=1 seek=39999504384 bs=1
	/sbin/mkfs.ext3 ./fs.img

9) Insert filesystem into a single disk

	# this will take a while, but preserves sparseness
	cp --sparse=always <(head -c 32256 disk.img ; cat fs.img) finaldisk.img

	# top up the resulting file
	dd if=/dev/zero of=finaldisk.img count=1 seek=40000000000 bs=1

10) Become root and do a loopback mount

	Note: sector 0 is unused, and is 63 sectors * 512 bytes per sector =
		32256 bytes

	mount -t ext3 -o loop,offset=32256 /tmp/finaldisk.img /mnt/loop

11) Copy over all necessary files... /etc, /dev, /bin, /boot, /usr, etc.
	Good old tar or 'cp -a' will do the trick.

12) Unmount


You now have a disk image the same as your host system.  If you want
multiple partitions in your VM, you'll have to repeat the filesystem
steps and do the sector math.

You can boot a rescue CD in the VM now, and just chroot into your
usual system.  That's the easiest.  Or you can fix up the boot sector
with grub or lilo.

Good luck, and have fun! :-)

- Chris





More information about the kwlug-disc mailing list