Migration of KVM virtual machine image to a raw disk partition

By Stephane Carrez 3 comments

This article explains how to move a KVM virtual disk image file from a plain file to a raw hard disk partition. It then explains how to grow the virtual disk to use the full partition size.

Why using a disk partition for the virtual machine image

Using a plain file for a virtual machine disk image is the easiest configuration when you setup some virtual machine environment. It allows to start quickly for the setup and you can copy easily the virtual machine for a backup.

However, using a raw disk partition for the virtual machine provides better performance in general. The overhead of the guest file system is avoided as we have a direct access to the partition.

Copy the virtual machine image on the partition

To copy the virtual machine image on our partition, the easiest way is to use the dd command. This step assumes that the virtual machine is stopped. In the example, the partition is /dev/sdb10, this partition is bigger than the image file (if this is not the case, the image will be truncated).

$ sudo dd if=windows-xp.img of=/dev/sdb10 bs=1048576
5120+1 records in
5120+1 records out
5368709121 bytes (5.4 GB) copied, 331.51 s, 16.2 MB/s

Resize the virtual disk to the full partition size

The virtual disk partition should be changed to use the full disk space provided by our /dev/sdb10 partition. For this, we can use the fdisk command:

$ sudo fdisk /dev/sdb10
Command (m for help): p
Disk /dev/sdb10: 22.0 GB, 22019042304 bytes
...
     Device Boot      Start         End      Blocks   Id  System
/dev/sdb10p1   *           1         651     5229126    7  HPFS/NTFS

You can easily change the partition to use the full disk by deleting the partition and creating it again so that you get something such as:

Device Boot Start End Blocks Id System

/dev/sdb10p1 1 2676 21494938+ 7 HPFS/NTFS

Now, we have to resize the file system on the virtual disk partition /dev/sdb10p1. For this, we will use kpartx to get access to the disk partitions provided by our /dev/sdb10 partition:

$ sudo kpartx -v -a /dev/sdb10
add map sdb10p1 (251:1): 0 42989877 linear /dev/sdb10 63

After the partitions are mapped, we can look at the filesystem before resizing it with the ntfsresize command. We use this command to know the good size for resizing the file system.

$ sudo ntfsresize --info /dev/mapper/sdb10p1
ntfsresize v2.0.0 (libntfs 10:0:0)
Device name        : /dev/mapper/sdb10p1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 5354623488 bytes (5355 MB)
Current device size: <b>22010817024</b> bytes (22011 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 4786 MB (89.4%)
Collecting resizing constraints ...
You might resize at 4785565696 bytes or 4786 MB (freeing 569 MB).
Please make a test run using both the -n and -s options before real resizing!

And we can do the resize by using the Current device size as the new file system size.

$ sudo ntfsresize -s 22010817024 /dev/mapper/sdb10p1
ntfsresize v2.0.0 (libntfs 10:0:0)
Device name        : /dev/mapper/sdb10p1
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 5354623488 bytes (5355 MB)
Current device size: 22010817024 bytes (22011 MB)
New volume size    : 22010810880 bytes (22011 MB)
Checking filesystem consistency ...
100.00 percent completed
Accounting clusters ...
Space in use       : 4786 MB (89.4%)
Collecting resizing constraints ...
WARNING: Every sanity check passed and only the dangerous operations left.
Make sure that important data has been backed up! Power outage or computer
crash may result major data loss!
Are you sure you want to proceed (y/[n])? y
Schedule chkdsk for NTFS consistency check at Windows boot time ...
Resetting $LogFile ... (this might take a while)
Updating $BadClust file ...
Updating $Bitmap file ...
Updating Boot record ...
Syncing device ...
Successfully resized NTFS on device '/dev/mapper/sdb10p1'.

At this stage, our virtual machine disk image was moved from a plain file to a raw disk partition that it uses entirely.

Change the virtual machine definition

The virtual machine definition must now be changed to use our partition. You can do this by copying the XML definition to another file, thus creating a new virtual machine. This is the best thing to do so that you can still use the old configuration. If you do such copy, you have to change the uuid as well as the network mac address.

The disk type parameter must be changed to block and the dev parameter must now point to the device partition.

<domain type='kvm'>
  ...
    <disk type='block' device='disk'>
      <source dev='/dev/sdb10'/>
      <target dev='hda' bus='ide'/>
    </disk>
    ...
</domain>

After this, start the virtual machine!

The next step is to setup virtio to boost performance by using paravirtualization.

Add a comment

To add a comment, you must be connected. Login

3 comments

bernd.lentes@helmholtz-muenchen.de
Bernd on 2011-11-13 08:22:07 said:

Hi Stephane,
thanks for the quick reply. Some more questions:
Don't i have direct access to the inner partition (sdb10p1) ? Or isn't there a suitable node in /dev ? So i need kpartx to create a node ?
You resize your inner partition from the host OS. Isn't that possible for my situation ?
1. Grow my /dev/vgx/lvx using lvextend
2. Change my inner partition table
3. Resize my fs from the host OS using resizefs (not from the booted vm)

How big is the gain of performance comparing vm in a plain partition and vm in a file ?

Bernd

bernd.lentes@helmholtz-muenchen.de
Bernd on 2011-10-27 18:13:14 said:

Hi,
this is very interesting for me because i want to move my virtual machines from VMWare to kvm. I'm thinking about installing them into plain partitions. How big is the gain of performance, compared with installing into files ?
How do i see the vm from the host OS in this situation ? As a "partition in a partition" ? (Because sdb10p1 looks like this). Can i mount this "partition" to access the fs, when the vm is not running ? Most of my vm's are Suse systems. How can i extend the fs if space is running out ? Shutdown the vm, extend the raw partition (which would be a LV in my case), "mount" the vm using kpartx and extend it using ext2online or resizefs ?

Bernd

rickard.lundin@sensate.se
Ludde on 2011-09-19 18:23:16 said:

Im making a "crazy" test , where i put the whole image under my host machines ramdisk /dev/shm.
My virtual machine has all its mount points inside this image.

It gave me 210Meg/sec. I switched to virtio which gave me 500Meg/sec.
This seems a bit slow since my host machine is a 24G/ram with i920 cpu , running ubuntu 11.04

guest os is ubuntu 11.04 with ext4 .. which might be stupid to use since the whole image is hosted in ramdisk ..what would be a better than ext4 here ?