Note

This functionality requires virt-v2v (https://www.libguestfs.org/virt-v2v.1.html) binary installed on destination cluster hosts (needs to be installed manually as it’s not a dependency of the CloudStack agent during the agent installation).

Requirements on the KVM hosts

The CloudStack agent does not install the virt-v2v binary as a dependency. The virt-v2v binary must be installed manually on KVM hosts, or the migration will fail.

Note

Newer versions of virt-v2v - v2.7.x on EL9 variants, v2.4.x on Ubuntu 24.04 - are strongly advised. Older versions of virt-v2v - e.g. v1.4.x should be avoided.

The virt-v2v output (progress) is logged in the CloudStack agent logs, to help administrators track the progress on the Instance conversion processes. The verbose mode for virt-v2v can be enabled by adding the following line to /etc/cloudstack/agent/agent.properties and restart cloudstack-agent:

dnf install virt-v2v / apt install virt-v2v

echo "virtv2v.verbose.enabled=true" >> /etc/cloudstack/agent/agent.properties

systemctl restart cloudstack-agent

Installing virt-v2v on Ubuntu KVM hosts does not install nbdkit, which is required in the conversion of VMware VCenter guests. To install it, please execute:

apt install nbdkit

Supported Distributions for KVM Hypervisor:

Linux Distribution

Supported Versions

Alma Linux

8, 9

Red Hat Enterprise Linux

8, 9

Rocky Linux

8, 9

Ubuntu

22.04 LTS, 24.04 LTS

Recommended distributions, due to the most recent virt-v2v version (EL9 prefered)

Linux Distribution

Versions

Alma Linux

9

Red Hat Enterprise Linux

9

Rocky Linux

9

Oracle Linux

9

Ubuntu

24.04 LTS

Importing Windows VMs from VMware requires installing the virtio drivers inside that Windows VMs and that is executed by the host running virt-v2v conversion. The Fedora-provided virtio-win RPM installs the drivers under /usr/share/virtio-win, which is one of virt-v2v’s default search paths.

On EL-based hosts, including RHEL, Oracle Linux, Rocky Linux and Alma Linux, install the Fedora-provided RPM directly.

dnf install -y https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.noarch.rpm

rpm -qa | grep -i virtio-win
ls -l /usr/share/virtio-win

For Debian-based distributions (alien is needed for conversion of .rpm to .deb package):

wget -O virtio-win.noarch.rpm https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.noarch.rpm
apt -y install alien
alien -d virtio-win.noarch.rpm

dpkg -i virtio-win*.deb
ls -l /usr/share/virtio-win

Note

Never rely on the virtio-win package from the Enterprise Linux distribution repositories: it lags the upstream project considerably and may contain no drivers at all for recent Windows releases (for example, the EL9 package 1.9.40 has no drivers for Windows Server 2025). virt-v2v then converts the guest without a virtio storage driver and the imported VM cannot boot from its virtio disk. If the guest’s Windows release is newer than the drivers in the installed RPM, overwrite the ISO with the latest upstream build:

curl -L -o /usr/share/virtio-win/virtio-win.iso https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso

Note

Windows Server 2025 enforces a stricter driver-signature policy at runtime and, as of virtio-win 0.1.285, rejects the optional smbus driver’s certificate during the first-boot driver installation. virt-v2v retries the failed installation on every boot, which leaves the imported guest in a reboot loop. The driver is a non-essential SMBus stub; the essential storage and network drivers install fine.

This affects Windows Server 2025 and newer only - older Windows releases (Windows Server 2016/2019/2022, Windows 10/11) accept the driver’s signature and work fine with the unmodified upstream ISO, so no action is needed for them. Until this is resolved in the virtio-win project, rebuild the ISO on the conversion host without the smbus files before converting Windows Server 2025 guests (virt-v2v reads the drivers from /usr/share/virtio-win/virtio-win.iso, so the ISO itself has to be modified):

dnf install -y xorriso

xorriso -osirrox on -indev /usr/share/virtio-win/virtio-win.iso -extract / /tmp/virtio-win-extracted
chmod -R u+w /tmp/virtio-win-extracted
find /tmp/virtio-win-extracted -iname 'smbus.*' -delete
xorriso -as mkisofs -o /usr/share/virtio-win/virtio-win.iso -J -R -V virtio-win /tmp/virtio-win-extracted
rm -rf /tmp/virtio-win-extracted

On some distros, the Windows helper binary “rhsrvany.exe”, which is used for Windows-based VM firstboot scripts and some other actions, might be missing.

To avoid virt-v2v error like virt-v2v: error: One of rhsrvany.exe or pvvxsvc.exe is missing in /usr/share/virt-tools - check if the file exists (it’s actually a symbolic link):

ls -la /usr/share/virt-tools/rhsrvany.exe

If the file does not exist, proceed with the commands below (EL8 and EL9 variants usually already have this in place, so are not affected)

Ubuntu-based distros

wget -nd -O srvany.rpm https://kojipkgs.fedoraproject.org/packages/mingw-srvany/1.1/4.fc38/noarch/mingw32-srvany-1.1-4.fc38.noarch.rpm
[ -f /usr/bin/alien ] || apt -y install alien
alien -d srvany.rpm
dpkg -i *srvany*.deb
mkdir -p /usr/share/virt-tools
ln -sf /usr/i686-w64-mingw32/sys-root/mingw/bin/rhsrvany.exe /usr/share/virt-tools/rhsrvany.exe
ln -sf /usr/i686-w64-mingw32/sys-root/mingw/bin/pnp_wait.exe /usr/share/virt-tools/pnp_wait.exe
ls -la /usr/share/virt-tools/rhsrvany.exe

The OVF tool (ovftool) must be installed on the destination KVM hosts if the hosts are to export VM files (OVF) from vCenter. If not, the management server exports them (the management server doesn’t require ovftool installed).

Download the ovftool from https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest

unzip VMware-ovftool-4.6.3-24031167-lin.x86_64.zip -d /usr/local/

#create a soft link

ln -s /usr/local/ovftool/ovftool /usr/local/bin/ovftool

If you are hitting the following error when running ovftool, install the dependency

./ovftool.bin: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory

dnf install libnsl

VDDK-based Optimized Conversion

CloudStack supports an optimized VMware-to-KVM migration path using virt-v2v in vpx input mode combined with VMware’s Virtual Disk Development Kit (VDDK). This method eliminates the OVF export phase entirely and streams disk blocks directly from the source hypervisor into the conversion pipeline, resulting in significantly faster migration times.

The traditional OVF-based workflow operates in two sequential phases:

  1. Export the entire VM as OVF/VMDK files to temporary storage (full disk copy).

  2. Convert the local VMDK files using virt-v2v (second full disk read and write).

The VDDK-based workflow replaces both phases with a single streaming pipeline:

  • virt-v2v connects directly to vCenter via vpx://

  • Disk blocks are read on demand via VDDK (using nbdkit internally as the translation layer between the VDDK API and virt-v2v’s NBD block device interface)

  • Conversion and disk transfer happen concurrently

  • Only allocated blocks are transferred; zero-filled and sparse extents are skipped

  • No intermediate OVF or VMDK files are created

This reduces disk I/O amplification, eliminates temporary staging storage, and shortens end-to-end migration time.

Note

CloudStack does not distribute VDDK, operators must download it separately. Along with the new VDDK-based conversion method, the traditional OVF-based method remains supported for environments. Operators can choose the conversion method on a per-migration basis in the UI import wizard.

Host Prerequisites for VDDK-based Conversion

To use VDDK-based migration, operators must prepare each KVM host that will run the conversion: install the conversion tools, install VDDK manually, configure libguestfs, and verify host connectivity to vCenter/ESXi.

Example: prepare one KVM conversion host

Step 1: Install the conversion stack

Install the required conversion tools on the KVM host. Choose the appropriate command for your distribution:

RHEL / Rocky / Alma Linux:

dnf install -y epel-release
dnf config-manager --set-enabled crb
dnf install -y virt-v2v libguestfs-tools libguestfs-xfs qemu-img nbdkit

Ubuntu:

apt install -y \
  virt-v2v \
  libguestfs-tools \
  libguestfs-xfs \
  qemu-utils \
  qemu-system-x86 \
  libvirt-clients \
  nbdkit

Step 2: Download and install VDDK

Download the VDDK Linux tarball from Broadcom’s VMware Virtual Disk Development Kit page: https://developer.broadcom.com/sdks/vmware-virtual-disk-development-kit-vddk/

Use the latest available VDDK 8.x Linux tarball for all supported KVM conversion hosts, including EL8, EL9, Ubuntu 22.04, and Ubuntu 24.04 hosts. VDDK 8.x covers vSphere 7 and vSphere 8 environments and is the recommended stable choice for most deployments. Do not use VDDK 9.x unless the source environment is vSphere 9 and the virt-v2v and nbdkit package combination has been explicitly validated, because VDDK 9.x is targeted at vSphere 9 and is not the expected default for vSphere 7 or vSphere 8 environments.

Extract the tarball under a consistent location such as the example below, and always configure that directory explicitly with the vddk.lib.dir property in /etc/cloudstack/agent/agent.properties (see the configuration reference further down). The agent does attempt to auto-detect a vmware-vix-disklib-distrib directory when the property is not set, but relying on auto-detection is strongly discouraged: on a real host the search can pick up the wrong VDDK libraries - leftovers from container images, a second VDDK installation, or a partially extracted tree - and the resulting conversion failures are hard to trace back to the wrong library path. Treat auto-detection as a fallback only; set vddk.lib.dir on every conversion host.

mkdir -p /opt/vmware-vddk

# VDDK 8.x example for EL8, EL9, Ubuntu 22.04, and Ubuntu 24.04 hosts
tar -xf VMware-vix-disklib-8*.tar.gz -C /opt/vmware-vddk

Expected layout after extraction:

/opt/vmware-vddk/vmware-vix-disklib-distrib/
  lib64/
  include/
  bin64/

Step 3: Verify host setup

nbdkit vddk --dump-plugin libdir=/opt/vmware-vddk/vmware-vix-disklib-distrib/lib64 | grep vddk_library_version
virt-v2v --version
nbdkit --version

Step 4: Restart the CloudStack agent

Restart the CloudStack agent service so it detects the installed VDDK library and makes it available in the UI:

systemctl restart cloudstack-agent

After the agent restarts, verify that VDDK installation was detected by checking the host details in the CloudStack UI.

Step 5: Verify required network and firewall access

Allow the following ports through any firewall or network security controls between the KVM conversion host and the VMware endpoints:

Target

Port

Purpose

vCenter

443

API / authentication

ESXi hosts

902

VDDK NFC disk transfer

ESXi hosts

443

VM metadata

Agent Properties for VDDK-based Conversion

The following properties can be configured in /etc/cloudstack/agent/agent.properties on each KVM host to enable and tune the VDDK-based conversion. After editing this file, restart the CloudStack agent (systemctl restart cloudstack-agent). These values can also be passed in details parameters in importVm API as key-value pairs.

Property

Description

Default / Example

vddk.lib.dir

Path to the VDDK library directory on the KVM host. Passed to virt-v2v as -io vddk-libdir=<path>.

/opt/vmware-vddk/vmware-vix-disklib-distrib

vddk.transports

Ordered VDDK transport preference. Passed as -io vddk-transports=<value> to virt-v2v.

Example: nbd:nbdssl

vddk.thumbprint

Optional vCenter SHA1 thumbprint. Passed as -io vddk-thumbprint=<value> to virt-v2v.

If unset, CloudStack computes it automatically on the KVM host via openssl.

Example configuration in /etc/cloudstack/agent/agent.properties:

# LIBGUESTFS backend to use for VMware to KVM conversion via VDDK (default: direct)
libguestfs.backend=direct

# Path to the VDDK library directory for VMware to KVM conversion via VDDK,
# passed to virt-v2v as -io vddk-libdir=<path>
vddk.lib.dir=/opt/vmware-vddk/vmware-vix-disklib-distrib

# Ordered VDDK transport preference for VMware to KVM conversion via VDDK, passed as
# -io vddk-transports=<value> to virt-v2v. Example: nbd:nbdssl
# vddk.transports=nbd:nbdssl

# Optional vCenter SHA1 thumbprint for VMware to KVM conversion via VDDK, passed as
# -io vddk-thumbprint=<value>. If unset, CloudStack computes it on the KVM host via openssl.
# vddk.thumbprint=

Recommendations for Using VDDK-based Conversion

VM state before conversion

  • Windows VMs: Must be powered off and gracefully shut down before conversion to ensure the filesystem is in a clean state.

Use a single primary storage pool for direct conversion

When VDDK-based conversion is enabled, it is strongly recommended to configure the conversion to write directly to the destination primary storage pool (i.e., set Convert to storage pool directly to true in the import wizard). This eliminates the two-step process of the traditional OVF method, conversion to temporary storage followed by an import step, replacing it with a single streaming pipeline that writes converted QCOW2 disks directly to the destination primary storage.

Network placement for optimal disk transfer throughput

For best performance, place the KVM conversion host on the same high-bandwidth network as the source ESXi hosts. VDDK disk transfer uses VMware’s NFC protocol on TCP port 902. ESXi routes NFC traffic to the conversion host based on standard IP routing, if the conversion host is reachable over a dedicated storage or migration network, ESXi will naturally select that VMkernel interface for disk transfer, keeping bulk data off the management network without requiring any special configuration in virt-v2v or CloudStack.

Usage

In the UI, Virtual Machines to import from VMware are listed in Tools > Import-Export Instances section, selecting:

Select Import-Export Source Hypervisor

Action

VMware

Migrate existing instances to KVM

Import VMware Virtual Machines into KVM.

Selecting the Destination cluster

CloudStack administrators must select a KVM cluster to import the VMware Virtual Machines (right side of the image above). Once a KVM cluster is selected, the VMware Datacenter selection part is displayed.

Selecting the VM from a VMware Datacenter

CloudStack administrators must select the Source VMware Datacenter:

  • Existing: The existing zones are listed, and for each zone, CloudStack will list if there is any VMware Datacenter associated with it. In case it is, it can be selected.

  • External: CloudStack allows listing Virtual Machines from a VMware Datacenter that is not associated with any CloudStack zone. To do so, the vCenter IP address, the datacenter name, and username and password credentials are needed to log in to the vCenter. To import from a standalone VMware host, you can use the default datacenter name (ha-datacenter or other) along with the host credentials (Only stopped VMs are supported).

Once the VMware Datacenter is selected, click on List VMware Instances to display the list of Virtual Machines in the Datacenter. You must then choose the VMware Instance for import and click on Import Instance.

Converting and importing a VMware VM

Note

CloudStack allows importing Running Linux Virtual Machines, but it is generally recommended that the Virtual Machine to import is powered off and has been gracefully shut down before the process starts. In case a Linux VM is imported while running, it will be converted in a “crash consistent” state. For Windows Virtual Machines, it is not possible to import them while running, they must be shut down gracefully so the filesystem is in a clean state.

Note

You can configure the parallel import of VM disk files on KVM host and management server, using the global settings: threads.on.kvm.host.to.import.vmware.vm.files and threads.on.ms.to.import.vmware.vm.files respectively.

Import VMware Virtual Machines into KVM Options.

In the UI import wizard, administrators can select:

  • (Optional) A KVM host to perform the conversion (must have virt-v2v installed). In case it is not set, then a KVM host is randomly selected.

  • (Optional) A KVM host to import the converted files into CloudStack (this host must have access to the temporary conversion storage in order to move the converted files to the destination storage). In case it is not set, then a KVM host is randomly selected.

  • (Optional) Extra parameters: in case the global setting convert.vmware.instance.to.kvm.extra.params.allowed (disabled by default) is enabled, then administrators are allowed to pass extra parameters for the virt-v2v conversion command. This setting must be set along with the setting convert.vmware.instance.to.kvm.extra.params.allowed.list (empty by default) which indicates the list of parameters that CloudStack will accept for passing to the virt-v2v conversion command on the KVM hosts.

Since version 4.22 it is possible to indicate converting to storage pool directly (not using temporary storage for conversion). This is set to false by default, in which case a temporary conversion storage is used.

  • When set to false (temporary storage used), then administrators must select a Temporary destination storage. The default is Secondary Storage, but if using Primary Storage - only NFS pools are supported.

  • When set to true (not using temporary storage), then administrators must select the destination storage pool. The supported storage pools are: NFS, Local Storage and SharedMountPoint storage pools, under the following assumptions:

  • The KVM host for conversion must be selected and must have access to the destination storage

  • The KVM host for importing must be selected and must have access to the destination storage

  • In case of Local storage, the selected KVM host for conversion must be the same as the KVM host for importing

Since version 4.22.1 it is possible to select the Guest OS for the VM to be imported, based on the source VMware VM Guest OS.

  • When CloudStack has Guest OS mappings for the source VMware Guest OS VM, then the list of supported Guest OS is displayed and administratos can select one of them.

  • In case there are no Guest OS mappings for the source VMware Guest OS VM, then the default import template Guest OS will be used.

The conversion is performed on a random (or explicitly chosen) KVM host (if the ovftools are installed), otherwise, the management server will export/copy the VM files (optionally, you can force this action to be done by the management server even the KVM hosts have the ovftools installed in it). Irrelevant if the KVM host or the management server performs the copy of the VM files (OVF), you can further either let CloudStack choose which KVM host should do the conversion of the VM files using virt-v2v and which host will import the files to the destination Primary Storage Pool, or you can explicitly choose these KVM hosts for each of the 2 mentioned operations.

When importing an instance from VMware to KVM (OVF method), CloudStack performs the following actions:

  • Export the VM files (OVF) of the instance to a temporary storage location (which can be selected by the administrator). The export is performed by a KVM host if ovftool is installed or management server (can be forced by the administrator, doesn’t need ovftool installed on the management server). The existence of ovftool on KVM host is checked using ovftool --version command.

    • If the instance on VMware is in running state, we clone the instance on VMware and use the new cloned instance to export OVF files. The cloning process may take some time to complete and is used to ensure data consistency, disk consolidation, etc.

    • If the instance on VMware is in stopped state, we directly use the instance to export its OVF files.

  • Converts the OVF on the temporary storage location to KVM using virt-v2v. CloudStack (or the administrator) selects a running and enabled KVM host to perform the conversion (of the previously exported OVF files) from VMware to KVM using virt-v2v. If the binary is not installed, then the host will fail to convert the Instance. In case it is installed, it will perform the conversion into the temporary location to store the converted QCOW2 disks of the instance. The virt-v2v conversion is a long-lasting process which can be set to time out by the global setting convert.vmware.instance.to.kvm.timeout. The conversion process takes a long time because virt-v2v creates a temporary instance to inspect the source VM and generate the converted disks with the correct drivers. Additionally, it needs to copy the converted disks into the temporary location.

  • The converted instance (i.e. QCOW2 files) is then imported into the chosen KVM cluster. Administrator can choose the KVM host to perform the import or let CloudStack choose it. Only enabled cluster and enabled hosts are considered.

Note

Please do not restart the management servers while migration is in progress as it will lead to the interruption of the process and you will need to start again.

Note

As mentioned above, the migration/conversion process uses an external tool, virt-v2v, which supports most but not all the operating systems out there (this is true for both the host on which the virt-v2v tool is running as well as the guest OS of the instances being migrated by the tool). Thus, the success of the import process will, almost exclusively, depend on the success of the virt-v2v conversion. In other words, the success will vary based on factors such as the current OS version, installed packages, guest OS setup, file systems, and others. Success is not guaranteed. We strongly recommend testing the migration process before proceeding with production deployments.

Note

The resulting imported VM uses the default Guest OS type: CentOS 4.5 (32-bit). After importing the VM, please Edit the Instance to change the Guest OS Type accordingly.

VM Import Tasks

Since version 4.22 administrators can monitor the VMware to KVM migration jobs. The new section is displayed on Tools > Import-Export Instances > Migrate existing instances to KVM > VM Import Tasks:

Listing Importing Tasks to Migrate VMware Virtual Machines into KVM.

The tasks can be filtered by state: Completed, Running or Failed, or listing all the tasks.