Migrating Windows VMs from VMware to OpenStack

If you haven’t tried it already, get a free on-demand trial for Mirantis OpenStack Express, now available.

The process of migrating a virtual machine running Microsoft Windows from VMware to Mirantis OpenStack Express is very similar to migrating from Amazon Web Services, with a few changes we’ll point out.  Most notably, if you don’t have Administrator access, you still have options for performing an export rather than starting from scratch.

If you have access to the administrator account on the Virtual Machine, proceed with opening ICMP through the Windows Firewall.

If you do not have Administrator access, follow these steps to copy the OEM files out of the Virtual Machine:

  1. Log into the Virtual Machine as an unprivileged user
  2. Navigate to C:\Windows\inf
  3. Copy all of the oem* files from that directory out of the virtual machine to a location where you can get them after shutting the virtual machine down
  4. Proceed with copying the VMDK files.

Open ICMP through the Windows Firewall via the GUI

Open a console session to the Windows Virtual Machine and allow ping (ICMP) through the Windows firewall by following these steps:
  1. From the Start menu, navigate to Control Panel -> System and Security and select Windows Firewall.  On the left side, click Advanced Settings:

  2. This will launch the Windows Firewall with Advanced Security window. In the left pane, click Inbound Rules which will show the rules in the right pane.
  3. In the right pane, find the rules that are titled File and Printer Sharing (Echo Request – ICMPv4-In).
  4. Right-click each rule and select Enable Rule:

Note: For detailed instructions on configuring the Windows Firewall for other versions of Windows, see these instructions.

You can also open the firewall from the command line.  Right-click the command prompt in the start window and choose Run as Administrator, then type following command and press Enter:

netsh advfirewall firewall add rule name="All ICMP V4"
protocol=icmpv4:any,any dir=in action=allow

(Credits for process detailed above go to from PC and Tablet.)

Configure RDP

To permit the ability to remote desktop into the Windows Virtual Machine, you need to allow remote connections to connect to the Virtual Machine.  Microsoft only supports Remote Desktop Connections on the following following versions of Windows:

  • Windows XP Professional edition
  • Windows Vista Business, Ultimate, or Enterprise edition
  • Windows 7 Professional, Ultimate, or Enterprise edition
  • Windows Server editions

On the existing Windows Virtual Machine, follow the following steps to enable Remote Desktop Connection:

  1. Open System Information by clicking the Start button , right-clicking Computer, and then clicking Properties.
  2. In the left pane, click Remote settings. If you’re prompted for an administrator password or confirmation, type the password or provide confirmation.
  3. Under Remote Desktop, select one of the options to allow connections. For more information about these options, see What types of Remote Desktop connections should I allow?
  4. Click Select Users.
  5. In the Remote Desktop Users dialog box, click Add.
    • In the Select Users or Groups dialog box, do one or more of the following:
    • To specify the search location, click Locations.
    • To specify the types of objects (user names) that you want to search for, click Object Types.
  6. In the Enter the object names to select box, type the user name that you want to search for, and then click Check Names. If the user name isn’t found, click Advanced to run an advanced search.
  7. When you find the correct name, click OK.
  8. The name will be displayed in the list of users in the Remote Desktop Users dialog box.
  9. Click OK, and then click OK again.

Next you need to allow Remote Desktop Connection through the Windows Firewall.  If you’re using Windows Firewall, follow these steps:

  1. Click the Start button , click Control Panel, type “firewall” in the search box, and then click Windows Firewall.
  2. Click Allow a program or feature through Windows Firewall.
  3. Under Allowed programs and features, scroll down to Remote Desktop and make sure its check box is selected.
  4. Under Home/Work (Private), make sure the checkbox next to Remote Desktop is selected.

If you’re using a non-Microsoft firewall, refer to the instructions that came with your firewall.

Credits: http://windows.microsoft.com/en-us/windows7/allow-remote-desktop-connections-from-outside-your-home-network

Install the VirtIO Drivers for Windows

In order to be able to migrate the machine, you’ll need to install the VirtIO driverson the source machine.  To do that, follow these steps:
  1. Start by downloading the VirtIO ISO image, which contains the necessary Windows drivers, from this location: http://alt.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/
  2. Mount the VirtIO ISO image that was downloaded at the start of this section.
  3. Attach the iso-file through system of emulations CD-ROM, e.g., Daemon Tools

  4. The installation procedure for the drivers is covered in the Red Hat documentation.
  5. Next, add the VirtIO drivers to the registry. Open Windows Registry Editor:
  • Click the Start button , type “regedit” in the search box, and then right click click regedit.exe and select Run as Administrator.

  • From here you can either import the registry configuration or make manual changes, as you choose:

Import registry configuration:

  1. Copy and paste the contents of Appendix C into a file with the extension of .reg
  2. In the Registry Editor, click File -> Import… and select the .reg file you saved in the previous step.
  3. Click Open. The file will import into the registry:

Manually enter the registry configuration:

If you’d rather not import a file into the registry of your virtual machine, you can make the necessary changes manually instead by following these steps:

  1. Open the Registry Editor.
  2. Open path:
  3. Change parameter “Service” to value “viostor”
  4. Change parameter “ClassGUID” to value  “{4D36E97B-E325-11CE-BFC1-08002BE10318}”
  5. Open path:
  6. Change parameter “Service” to value “viostor”
  7. Change parameter “ClassGUID” to value “{4D36E97B-E325-11CE-BFC1-08002BE10318}”
  8. Open path:
  9. Change parameter “Service” to value “viostor”
  10. Change parameter “ClassGUID” to value “{4D36E97B-E325-11CE-BFC1-08002BE10318}”
  11. Navigate through the following paths in the registry making the following changes:
  • "Type"=dword:00000001
  • "Start"=dword:00000000
  • "Group"="SCSI miniport"
  • "ErrorControl"=dword:00000001
  • "ImagePath"="system32\\drivers\\viostor.sys"
  • "Tag"=dword:00000021
  • "BusType"=dword:00000001
  • "ParamDesc"="Maximum Transfer Size"
  • "type"="enum"
  • "default"="0"
  • "0"="64  KB"
  • "1"="128 KB"
  • "2"="256 KB"
  • "5"=dword:00000001
  • "0"="PCI\\VEN_1AF4&DEV_1001&SUBSYS_00021AF4&REV_00\\3&13c0b0c5&0&20"
  • "Count"=dword:00000001
  • "NextInstance"=dword:00000001

Copy VMDK Files

Next you’ll need to retrieve the VMDK files that make up the virtual machine so that you can convert them into an image that OpenStack understands.  Follow these steps:

  1. Shut down the virtual machine.
  2. Locate the VMDK files by selecting Edit Settings on the Virtual Machine in vCenter and clicking on the Hard Disk to see the location of the file:

    virtual machine properties
    Note: If the Virtual Machine has multiple hard disks allocated to it, the process to migrate it into OpenStack becomes more complicated.  If you wish to attempt this, please refer to these instructions: https://ask.openstack.org/en/question/5358/how-to-import-a-vmware-vm-with-multiple-drives/
  3. Copy the VMDK file from the datastore:

    Note: If your Virtual Machine was created in VMWare Workstation or VMware Fusion, it’s possible you don’t have a single *-flat.vmdk that you need and instead have multiple VMDK files that make up the single disk:

    If this is the case, you will require the Virtual Disk Development Kit from VMware. See Appendix B for installation and usage of the toolkit to merge the multiple VMDK files into a single flat VMDK.
  4. After downloading the VMDK image from the datastore, you need to place it on a Linux system to utilize the qemu-img tools to convert it to the appropriate QCOW2 format.  You can create a Linux Virtual Machine and install the qemu-img package or you can utilize the Controller Node of your OpenStack environment.  See the Navigating Mirantis OpenStack Express section of this document for obtaining access to the Controller Node of Mirantis OpenStack Express and uploading the VMDK image.

    NOTE: If your VMDK is a large file, ensure that there is at least 2.5x the space available on your Controller Node before uploading it to the controller node.
  5. Upload the VMDK file to the Controller Node (or optionally a VM that has both the qemu-img) to the mirantis user home directory.
  6. SSH in as the mirantis user and convert the VMDK to a QCOW2 format by issuing the following command:
    qemu-img convert -f {initial format} -O {target format} {source file} {destination file}

    For example:

    qemu-img convert -f vmdk -O qcow2 VM.vmdk VM.qcow2
  7. If you had administrator access to this Windows Virtual Machine, you are ready to upload your image to OpenStack as detailed in the uploading image to OpenStack section of this document.  If you did not have Administrator access to this Windows Virtual Machine, you must proceed with the steps in the next section.  

Inject the VirtIO drivers

Even though you installed the VirtIO drivers on the original virtual machine, you will need to inject them into the QCOW2 image before trying to launch the image on OpenStack.  You’ll do this using a program called guestfish on a Linux machine.  Follow these steps:

  1. If you are running guestfish on the Controller Node, you need to execute the following line so that guestfish knows where to locate qemu-kvm binary:
    export LIBGUESTFS_QEMU=$(rpm -ql qemu-kvm | grep qemu-kvm$)
  2. Upload the following files to the same location that you stored the VMDK file in the previous section:
    • VirtIO ISO file (Downloaded at the start of the Windows Virtual Machine migation section)
    • All oem* files you copied out of the Virtual Machine prior to powering it off
  3. Log in to the controller node (or whichever node you’re using) as root and mount the VirtIO ISO so we can copy files out of it:
    [root@node-2 ~]# mkdir -p /mnt/virtio
    [root@node-2 ~]# mount -t iso9660 -o loop
    ~mirantis/virtio-win-0.1-74.iso /mnt/virtio
  4. Next, SSH in as the mirantis user and create a folder structure to be used to inject the VirtIO drivers into the QCOW2 image using guestfish:
    mkdir -p ~/Drivers/inf ~/Drivers/system32/drivers
  5. Copy the files from the win7/amd64 directory into the inf folder:
    [mirantis@node-2 ~]$ cp /mnt/virtio/win7/amd64/* Drivers/inf >/dev/null
    [mirantis@node-2 ~]$ ls Drivers/inf/
    balloon.cat  balloon.sys  netkvm.catnetkvm.pdb  vioscsi.cat  vioscsi.sys  vioser.pdb   vioser-test.pdb  viostor.pdb
    balloon.inf  blnsvr.exe   netkvmco.dll  netkvm.sys  vioscsi.inf  vioser.cat   vioser.sys   viostor.cat  viostor.sys
    balloon.pdb  blnsvr.pdb   netkvm.infreadme.doc  vioscsi.pdb  vioser.inf   vioser-test.exe  viostor.inf  wdfcoinstaller01009.dll
  6. Copy the oem* files into place:
    [mirantis@node-2 ~]$ cp oem* Drivers/inf/
    [mirantis@node-2 ~]$ ls Drivers/inf/
    balloon.cat  blnsvr.exenetkvm.inf  oem2.PNF  oem4.PNF  oem6.PNF vioscsi.pdb  vioser.pdb   viostor.cat  wdfcoinstaller01009.dll
    balloon.inf  blnsvr.pdbnetkvm.pdb  oem3.inf  oem5.inf  readme.doc   vioscsi.sys  vioser.sys   viostor.inf
    balloon.pdb  netkvm.catnetkvm.sys  oem3.PNF  oem5.PNF  vioscsi.cat  vioser.cat   vioser-test.exe  viostor.pdb
    balloon.sys  netkvmco.dll  oem2.infoem4.inf  oem6.inf  vioscsi.inf  vioser.inf   vioser-test.pdb  viostor.sys
  7. Lastly, store these files the Drivers folder:
    [mirantis@node-2 ~]$ for X in balloon.sys netkvm.sys vioscsi.sys vioser.sys viostor.sys; do cp /mnt/virtio/win7/amd64/${X} Drivers/system32/drivers; done
    [mirantis@node-2 ~]$ ls Drivers/system32/drivers/*
    Drivers/system32/drivers/balloon.sys  Drivers/system32/drivers/vioscsi.sys  Drivers/system32/drivers/viostor.sys
    Drivers/system32/drivers/netkvm.sys   Drivers/system32/drivers/vioser.sys
  8. Now we will create a quick bash shell script to perform the injection.  Launch your favorite editor (nano, emacs, vi, etc) and copy/paste the following into a script called inject.sh:
    guestfish --rw -a $1 -i <<_EOF_
    upload Drivers/Inf/BALLOON.CAT 'win:\windows\inf\BALLOON.CAT'
    upload Drivers/Inf/BALLOON.INF 'win:\windows\inf\BALLOON.INF'
    upload Drivers/Inf/BALLOON.PDB 'win:\windows\inf\BALLOON.PDB'
    upload Drivers/Inf/BALLOON.SYS 'win:\windows\inf\BALLOON.SYS'
    upload Drivers/Inf/BLNSVR.PDB 'win:\windows\inf\BLNSVR.PDB'
    upload Drivers/Inf/NETKVM.CAT 'win:\windows\inf\NETKVM.CAT'
    upload Drivers/Inf/NETKVMCO.DLL 'win:\windows\inf\NETKVMCO.DLL'
    upload Drivers/Inf/NETKVM.INF 'win:\windows\inf\NETKVM.INF'
    upload Drivers/Inf/NETKVM.PDB 'win:\windows\inf\NETKVM.PDB'
    upload Drivers/Inf/NETKVM.SYS 'win:\windows\inf\NETKVM.SYS'
    upload Drivers/Inf/oem2.inf 'win:\windows\inf\oem2.inf'
    upload Drivers/Inf/oem2.PNF 'win:\windows\inf\oem2.PNF'
    upload Drivers/Inf/oem3.inf 'win:\windows\inf\oem3.inf'
    upload Drivers/Inf/oem3.PNF 'win:\windows\inf\oem3.PNF'
    upload Drivers/Inf/oem4.inf 'win:\windows\inf\oem4.inf'
    upload Drivers/Inf/oem4.PNF 'win:\windows\inf\oem4.PNF'
    upload Drivers/Inf/oem5.inf 'win:\windows\inf\oem5.inf'
    upload Drivers/Inf/oem5.PNF 'win:\windows\inf\oem5.PNF'
    upload Drivers/Inf/oem6.inf 'win:\windows\inf\oem6.inf'
    upload Drivers/Inf/oem6.PNF 'win:\windows\inf\oem6.PNF'
    upload Drivers/Inf/VIOSCSI.CAT 'win:\windows\inf\VIOSCSI.CAT'
    upload Drivers/Inf/VIOSCSI.INF 'win:\windows\inf\VIOSCSI.INF'
    upload Drivers/Inf/VIOSCSI.PDB 'win:\windows\inf\VIOSCSI.PDB'
    upload Drivers/Inf/VIOSCSI.SYS 'win:\windows\inf\VIOSCSI.SYS'
    upload Drivers/Inf/VIOSER.CAT 'win:\windows\inf\VIOSER.CAT'
    upload Drivers/Inf/VIOSER.INF 'win:\windows\inf\VIOSER.INF'
    upload Drivers/Inf/VIOSER.PDB 'win:\windows\inf\VIOSER.PDB'
    upload Drivers/Inf/VIOSER.SYS 'win:\windows\inf\VIOSER.SYS'
    upload Drivers/Inf/VIOSER-TEST.PDB 'win:\windows\inf\VIOSER-TEST.PDB'
    upload Drivers/Inf/VIOSTOR.CAT 'win:\windows\inf\VIOSTOR.CAT'
    upload Drivers/Inf/VIOSTOR.INF 'win:\windows\inf\VIOSTOR.INF'
    upload Drivers/Inf/VIOSTOR.PDB 'win:\windows\inf\VIOSTOR.PDB'
    upload Drivers/Inf/VIOSTOR.SYS 'win:\windows\inf\VIOSTOR.SYS'
    upload Drivers/Inf/WDFCOINSTALLER01009.DLL 'win:\windows\inf\WDFCOINSTALLER01009.DLL'
    upload Drivers/system32/drivers/BALLOON.sys 'win:\windows\system32\drivers\BALLOON.sys'
    upload Drivers/system32/drivers/netkvm.sys 'win:\windows\system32\drivers\netkvm.sys'
    upload Drivers/system32/drivers/vioscsi.sys 'win:\windows\system32\drivers\vioscsi.sys'
    upload Drivers/system32/drivers/vioser.sys 'win:\windows\system32\drivers\vioser.sys'
    upload Drivers/system32/drivers/viostor.sys 'win:\window
  9. Press Ctrl+D and and launch the script, passing the filename of the QCOW2 file:
    ./inject.sh ./vm.qcow2
  10. Now we will prepare a reg file for registry injection. Create a text file and name it virtio.reg. Add the following text:
    Windows Registry Editor Version 5.00
    "Group"="SCSI miniport"
    "ParamDesc"="Maximum Transfer Size"
    "0"="64  KB"
    "1"="128 KB"
    "2"="256 KB"

    This file is also available here

  11. Inject the file by typing:
    virt-win-reg --merge {Disk name}.qcow2 {file name}

    For example:

    virt-win-reg --merge VM.qcow2 virtio.reg
  12. At this point you are ready to upload your image to OpenStack.  Since you’re already logged into the Controller Node, utilize the CLI to perform the upload as detailed in the upload images section.

Launch the new instance

At this point, you have a new Windows-based image that you can use to launch a new instance on OpenStack.  You can accomplish this through the command-line or the OpenStack Horizon dashboard; we’ll use Horizon in this example.  Follow these steps to launch the new image:
  1. Log into the Horizon dashboard using the credentials from the Mirantis OpenStack Express dashboard or the Fuel control plane.
  2. Navigate to Projects -> Instances.
  3. Click the +Launch Instance button.

  4. Enter the necessary information about your new instance.  Make sure to specify your new image as the image for your new instance.

    launch instance
  5. Click Access & Security and specify a keyfile, or create a new one.
  6. Click Networking and drag one of the Available networks up to Selected Networks.
  7. Click Launch
  8. Wait until the status changes to Running.

    instance name
  9. To work with the virtual machine choose More->Console.

    instance console

At this point your migration is complete.  Congratulations!

Want to read more?  This article is an excerpt from our new guide, Mirantis OpenStack Express: Application On-boarding Guide (currently in beta).  Please let us know what you think.

Subscribe to Our Newsletter

Latest Tweets

Suggested Content

Mirantis Cloud Platform
Machine Learning in the Datacenter