| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
This document describes the VMware Changed Block Tracking (CBT) migration design and implementation for Apache CloudStack 24.0.0. It is written as source material for an Apache CloudStack CWIKI architecture page and should be treated as an implementation guide, not only as a design sketch.
The feature provides a warm VMware-to-KVM migration flow. CloudStack creates a KVM-side source-equivalent disk replica from a VMware VDDK snapshot, keeps that replica current with one or more VMware CBT delta cycles, requires the operator to power off the VMware source VM, runs one final CBT delta cycle, finalizes the replica with virt-v2v, and imports the finalized disk(s) as a regular CloudStack KVM VM.
The essential architectural point is that VMware CBT migration is a two-phase disk strategy:
This gives CloudStack warm migration behavior without trying to apply VMware changed blocks to a disk that has already been transformed for KVM, and without requiring a second full VMware read at cutover time.
The existing VMware import paths are useful for one-time imports, but they do not provide a warm migration loop where the target disk is kept current while the source VM continues to run on VMware. Large VMs therefore either require a longer downtime window or repeated full-copy style attempts.
VMware CBT provides the changed-block metadata needed for a replication-style workflow, but the design must avoid a common trap: once virt-v2v modifies a disk for KVM guest bootability, VMware CBT byte ranges can no longer be safely applied to that transformed disk. The implementation must therefore keep the replication target source-equivalent until final cutover, then run guest conversion only after the final delta is applied.
Current implementation scope:
Not implemented or intentionally blocked:
The implementation has four main layers:
Management-server API and orchestration:
Persistence:
KVM agent wrappers:
UI:
The diagrams below are intentionally plain text so they can be pasted directly into Apache CWIKI source and remain editable.
VMware source VM
|
| VMware snapshot + CBT metadata
v
VDDK / nbdkit-vddk on KVM conversion host
|
| Initial baseline: full logical disk read
v
CloudStack primary storage
|
| Source-equivalent replica
| - qcow2 file on filesystem-like storage
| - raw RBD image on Ceph/RBD storage
v
Delta sync cycles
|
| CBT changed ranges only
v
Operator powers off source VM
|
| Cutover: final delta + virt-v2v finalization
v
CloudStack KVM VM
VMware CBT initial sync is not guest-filesystem-used-space-oriented. CloudStack does not inspect the guest filesystem to decide which files are in use; it reads the disk image exposed by VDDK/NBD and writes the target replica.
The amount of data transferred depends on what VDDK exposes for the source disk and datastore. Some source paths expose the baseline as one allocated logical range, while others expose sparse hole,zero extents. The destination can remain thin or sparse when the source and copy path expose zero ranges correctly, but operators must size the initial-copy window for the full logical disk capacity.
The KVM agent uses qemu-img convert for the general full-copy path. When nbdcopy is installed, it can accelerate supported pre-created raw targets and RBD targets served through a local qemu-nbd bridge. nbdcopy is optional; capability and correctness do not depend on it.
Example VMware disk capacity: 5 GiB
Guest-used data: near 0 GiB
Datastore/path behavior: datastore-dependent
During initial sync:
VMware/VDDK exposes allocation/extents to NBD.
CloudStack reads the ranges that qemu sees through that NBD export.
qemu-img writes a qcow2 target and can preserve thin/sparse output.
Possible outcome: full logical transfer or sparse-aware transfer
Target allocation: backend- and extent-dependent
The initial baseline reads the logical disk presented by VDDK. Linked clone vs full clone is not enough by itself to predict transfer volume. The decisive question is whether VDDK/NBD exposes trustworthy allocation and zero extents for the source datastore and disk chain.
Linked clone source
child delta VMDK
|
v
parent/base VMDK chain
|
v
VDDK presents one logical disk
Full clone source
single/full VMDK
|
v
VDDK presents one logical disk
CBT initial sync:
both are read as the full logical disk capacity.
The target qcow2 can still be sparse/thin after the write.
Initial sync completed
|
v
Delta cycle 1 -> changed bytes / dirty rate measured
|
v
Delta cycle 2 -> quiet-cycle counters updated
|
v
Repeat until one boundary is met:
min cycles satisfied
AND quiet bytes threshold satisfied
AND quiet dirty-rate threshold satisfied
AND quiet cycle count satisfied
OR
max cycle count reached
|
v
Migration becomes ReadyForCutover
Final CBT delta sync
|
v
Check selected conversion host capability
|
+--> virt-v2v-in-place available
| |
| v
| run virt-v2v-in-place finalization
|
+--> virt-v2v supports --in-place
| |
| v
| run virt-v2v --in-place finalization
|
+--> non-in-place fallback explicitly allowed
|
v
run regular virt-v2v -o local fallback finalization
Result:
finalized qcow2 moved to primary storage root
VM imported with VirtIO root disk controller
During sync:
/mnt/<pool-uuid>/cloudstack-cbt/<migration-uuid>/...
After finalization/import:
/mnt/<pool-uuid>/<generated-volume-uuid>.qcow2
CloudStack DB target path:
updated to the final primary-storage-root location
checkVmwareCbtMigrationPrerequisites validates the source and destination before a long-running job is started. The command is synchronous and returns a structured preflight response with pass, warn, and fail findings.
The preflight checks include:
The preflight response includes, among other fields:
If CBT is supported but not enabled, preflight reports a warning. The start path can enable CBT before creating the baseline snapshot.
The source guest OS fields are populated from the VMware inventory and are used to decide whether Windows-specific conversion prerequisites apply. They do not change the migration mode or disk-copy behavior by themselves.
VMware exposes more than one guest OS signal. The VM's configured guest OS option can differ from the runtime guest OS label reported by VMware Tools. For example, a powered-on VM can show Ubuntu Linux (64-bit) in the vSphere summary while VM Options still show Other (64-bit). CloudStack discovery and preflight therefore treat source guest OS values as inventory facts rather than as a safe automatic target OS selection.
The target CloudStack guest OS is the optional osid supplied to startVmwareCbtMigration and used later by the shared KVM import path. Operators should verify this value before starting migration, especially for generic VMware guest IDs such as ubuntu64Guest, which can represent multiple Ubuntu releases. If the desired target guest OS is not selectable, the corresponding guest_os_hypervisor mapping must exist for the source hypervisor version.
startVmwareCbtMigration is async. It creates the migration record, persists source disk rows, creates a baseline VMware snapshot, prepares target paths, and dispatches the initial full sync to the selected KVM host.
For Windows source VMs, the start path repeats the same conversion dependency check reported by preflight before the baseline snapshot and initial sync are started. This prevents a long CBT copy from producing a disk that cannot be made bootable because the selected KVM conversion host is missing virtio-win.
State transitions:
Important implementation details:
syncVmwareCbtMigration is async and serialized by migration ID through BaseAsyncCmd.migrationSyncObject.
Allowed migration states:
Delta cycle sequence:
The cycle response exposes:
Delta sync progress is represented as state and cycle metadata rather than a streamed progress bar. While a cycle is running, the row description can show what the manager knows, for example that changed areas are being queried or that a number of ranges has been dispatched. After the agent returns, the cycle shows copied bytes, dirty rate, duration, and a textual summary.
cutoverVmwareCbtMigration is async and serialized by migration ID.
Allowed migration states:
Cutover requires the source VM to be powered off. CloudStack checks the VMware power state and rejects cutover if the source VM is still powered on:
Cannot cut over VMware CBT migration <uuid> while source VM <name> is in power state PowerOn.
Gracefully shut down the source VM, then retry cutover.
CloudStack does not attempt a graceful shutdown or power-off. The operator must shut down the VMware source VM before final cutover. This avoids surprising the operator and avoids needing to encode site-specific guest shutdown policy in the migration path.
Cutover sequence:
cancelVmwareCbtMigration is synchronous. If the migration is not terminal, it sends a best-effort cleanup command, marks the migration Cancelled, and clears stored external vCenter credentials.
deleteVmwareCbtMigration is synchronous. It is allowed for Failed, Cancelled, and Completed migrations. With cleanup=true (the default), it sends a cleanup command before deleting failed or cancelled child rows and the parent row. Completed migration deletion is always record-only: CloudStack removes the CBT bookkeeping rows but never deletes the imported VM, CloudStack volumes, finalized target disks, or primary-storage files.
Deletion behavior:
The KVM cleanup wrapper resolves migration directories from disk target paths and removes only the migration-specific directory tree for file targets. For RBD targets it uses the destination storage pool and deletes only marked temporary images, never arbitrary RBD images.
The feature deliberately separates replication from final conversion.
Initial full sync does not run virt-v2v. The KVM agent opens the VMware source snapshot through nbdkit with the VDDK plugin. Filesystem-like primary storage writes QCOW2 with qemu-img convert:
nbdkit -r -U - vddk ... --run \
'qemu-img convert -f raw -O qcow2 "$uri" "<targetPath>"'
Ceph/RBD primary storage is a raw RBD image. When nbdcopy is available, the agent pre-creates the image, exposes it through a temporary local qemu-nbd bridge, and copies NBD to NBD. Otherwise it uses qemu-img convert directly against the qemu RBD URL. LINSTOR similarly uses nbdcopy when available for its pre-created raw DRBD device and falls back to qemu-img convert.
Example RBD fallback path:
nbdkit -r -U - vddk ... --run \
'qemu-img convert -f raw -O raw "$uri" "rbd:<pool>/<image>:..."'
This produces a source-equivalent replica on the selected primary storage. It is not yet a CloudStack-imported VM disk. It is a replication target that can safely receive raw changed blocks from later CBT cycles.
Delta sync also does not run virt-v2v. Management creates a VMware snapshot, queries changed disk areas using VMware CBT metadata, and dispatches changed byte ranges to the KVM agent. The agent opens the snapshot through nbdkit, parses the temporary nbdkit Unix socket from the NBD URI, uses qemu-img convert --image-opts to materialize bounded raw chunks for only the changed ranges, and patches the replica with qemu-io. File targets use -f qcow2; RBD targets use -f raw against the qemu RBD URL for the target image.
Final cutover is where virt-v2v runs. After the source VM is powered off, the manager runs one final CBT delta cycle so the replica is current. Then the agent runs one of the finalization paths:
Ceph/RBD targets require one of the in-place finalization paths. They do not allow non-in-place fallback because fallback creates local QCOW2 output rather than modifying the raw RBD image that CloudStack will import.
So there is not a second full VMware read during finalization. The final virt-v2v step is local work against the up-to-date KVM-side replica. It may still require local storage reads and writes, especially in fallback mode, but it is not another VDDK full copy from vCenter.
The initial baseline may read up to the full logical VMware disk range, regardless of guest filesystem usage. This does not imply thick allocation on the destination: QCOW2, RBD, and LINSTOR can remain sparse or thin when the source and copy path expose zero ranges correctly. Delta cycles are CBT-range based and copy only changed ranges.
This design avoids applying future CBT raw block deltas to a disk that has already been modified by virt-v2v. Applying VMware CBT ranges to a converted guest disk would be unsafe because the layout no longer represents the source VMware disk byte-for-byte.
All commands are admin-only.
Synchronous preflight command.
Required:
Source vCenter selection:
Optional:
The command has requestHasSensitiveInfo=true because external vCenter credentials can be provided.
Async command. Starts the migration and initial full sync.
Required:
Source vCenter selection:
Optional import inputs:
Optional conversion inputs:
If convertinstancestoragepoolid is omitted, CloudStack auto-selects the only CBT-compatible primary storage pool in the destination cluster/zone. Supported target pool types are NetworkFilesystem, Filesystem, SharedMountPoint, and RBD. If more than one compatible pool is available, the operator must provide the pool explicitly.
Useful details keys:
The command has requestHasSensitiveInfo=true and responseHasSensitiveInfo=false.
Synchronous status command and the main progress source for UI and automation.
Filters:
The response includes migration-level state, current step, current step duration, last error, cycle counters, changed byte totals, disks, and cycles. currentstepduration is populated for non-terminal migrations and is intended for the UI table marker similar to Import VM Tasks.
Async command. Runs one delta sync cycle.
Required:
Optional:
For an external vCenter migration, stored credentials are used when available. If override credentials are supplied, both username and password must be provided. Overrides are stored back to the migration so a UI operator can return later and continue syncing.
Async command. Runs final powered-off sync, finalizes disks, and imports the VM.
Required:
Optional:
The command fails early if the source VMware VM is not powered off.
Synchronous command.
Required:
Cancels a non-terminal migration, attempts cleanup, and clears stored external source credentials.
Synchronous command.
Required:
Optional:
Allowed for Failed, Cancelled, and Completed migrations. Completed migration deletes are record-only and never remove the imported CloudStack VM, volumes, finalized target disks, or primary-storage files.
The cutover recommendation is based on global settings:
| Global setting | Default | Meaning |
|---|---|---|
| vmware.cbt.migration.min.cycles | 1 | Minimum number of manual/API delta cycles that must complete before quiet-cycle readiness can make the migration eligible for cutover. |
| vmware.cbt.migration.max.cycles | 5 | Maximum number of manual/API delta cycles before CloudStack marks the migration ready for cutover even if the quiet-cycle thresholds were not met. |
| vmware.cbt.migration.quiet.cycles | 2 | Number of consecutive quiet cycles required before CloudStack marks the migration ready for cutover. |
| vmware.cbt.migration.quiet.bytes | 1073741824 | Maximum changed bytes in one cycle for that cycle to be considered quiet. The default is 1 GiB. |
| vmware.cbt.migration.quiet.dirty.rate | 16777216 | Maximum changed bytes per second for that cycle to be considered quiet. The default is 16 MiB/s. |
| vmware.cbt.migration.agent.command.timeout | 86400 | Timeout in seconds for long-running VMware CBT data-plane commands on the KVM agent. This covers initial full sync, regular delta sync, final delta sync, and cutover finalization. The default is 24 hours. |
The manager tracks:
A cycle is quiet when its changed bytes and dirty rate are below the configured thresholds. Both thresholds must pass. For example, with defaults, a cycle that copies 1.2 GiB at 10 MiB/s is not quiet because the changed-byte threshold is exceeded even though the dirty-rate threshold passed.
Once enough quiet cycles have accumulated, or once the maximum manual/API delta-cycle count is reached, the migration moves to ReadyForCutover.
The operator can still manually run sync cycles while the migration is in Replicating or ReadyForCutover.
The UI intentionally exposes the Cutover button only when the server-side migration state is exactly ReadyForCutover. Before that point the UI exposes Sync delta, because the server has not yet recommended final cutover. If a cutover is started, CloudStack creates one additional final CBT delta cycle inside the cutover operation. Therefore the final displayed cycle count can be one higher than vmware.cbt.migration.max.cycles: for example, five ordinary delta cycles can make the migration ready, and cutover can then record cycle 6 as the final synchronization cycle.
The long-running CBT work is done by KVM agent commands. CloudStack sets the agent command wait value from vmware.cbt.migration.agent.command.timeout, and the KVM wrappers use the same value as the timeout for child processes such as nbdkit, qemu-img, and virt-v2v.
The timeout is finite by design. The shared CloudStack Script helper treats a zero timeout as its default one-hour timeout, so 0 is not a safe way to mean "run forever". For large source disks, tune the timeout above the expected worst-case duration. A rough estimate is:
timeout_seconds >= source_bytes / expected_bytes_per_second * safety_factor
For example, a 1 TiB initial sync at 100 MiB/s is roughly 3 hours before overhead; at 25 MiB/s it is roughly 12 hours. The default 24-hour timeout is intended to be safe for large migrations while still protecting the agent from permanently stuck child processes.
Related import settings that operators often notice are:
| Global setting | Applies to CBT? | Default | Meaning |
|---|---|---|---|
| convert.vmware.instance.to.kvm.timeout | No | 3 | OVF/VDDK import timeout, in hours, for the ConvertInstanceCommand virt-v2v path. CBT cutover has its own timeout because it uses CBT-specific agent commands. |
| remote.kvm.instance.disks.copy.timeout | No | 30 | Remote KVM unmanaged import disk-copy timeout, in minutes. It is unrelated to VMware CBT. |
If a CBT command exceeds vmware.cbt.migration.agent.command.timeout, the migration is marked failed with the agent error details in last_error. Failed or cancelled migration records can be deleted with cleanup enabled to remove CloudStack-owned cloudstack-cbt/<migration-uuid> working files.
The feature targets the Apache CloudStack 24.0.0 release, so the schema changes are delivered through the canonical 4.23.0.0 to 24.0.0 upgrade path:
One row per migration session.
Important columns:
source_password is annotated with @Encrypt in VmwareCbtMigrationVO, using the same CloudStack encrypted DAO field mechanism used by VMware datacenter credentials and VM VNC passwords.
One row per source VMware disk.
Important columns:
Disk states:
One row per delta cycle.
Important columns:
Cycle states:
Migration states:
Terminal states:
Normal successful path:
Created
-> InitialSync
-> Replicating
-> ReadyForCutover
-> CuttingOver
-> ReadyForImport
-> Completed
ReadyForImport is intentionally retryable. If the final virt-v2v finalization succeeded but CloudStack VM import failed, the next cutover command does not rerun the final CBT copy and finalization. It retries the VM import against the already finalized disk paths.
VmwareCbtStorageTarget maps primary storage to a target writer:
For QCOW2 file targets, the initial replica is stored under the selected primary storage:
/mnt/<pool-uuid>/cloudstack-cbt/<migration-uuid>/<disk>.qcow2
If no storage pool is selected, the fallback path is:
/var/lib/libvirt/images/cloudstack-cbt/<migration-uuid>/<disk>.qcow2
For Ceph/RBD targets, the initial replica is a raw RBD image in the selected pool:
<ceph-pool>/cloudstack-cbt-<migration-uuid>-<source-disk-id>-<source-name>
Only the image name is persisted as the migration disk target path. The agent reconstructs the qemu RBD URL from the selected storage pool when writing initial and delta data. During in-place virt-v2v finalization, the agent starts a temporary localhost qemu-nbd bridge for each RBD image and gives virt-v2v a libvirt XML disk that points to that local NBD endpoint. This keeps RBD credentials and monitor options in the qemu layer and presents a local NBD endpoint to the conversion appliance.
The preferred cutover finalization is in-place:
If neither in-place method is available, QCOW2 file targets can use regular virt-v2v -o local only when this global configuration is enabled:
vmware.cbt.allow.non.inplace.finalization=true
Default:
false
When fallback is enabled:
Fallback is never allowed for RBD targets. RBD migrations require virt-v2v-in-place or virt-v2v --in-place support on the selected conversion host.
Example fallback output path:
/mnt/<pool-uuid>/cloudstack-cbt/<migration-uuid>/virt-v2v-output-<random>/<migration-uuid>-sda
After successful finalization, both in-place and fallback paths are normalized to the same final layout used by the OVF/VDDK import flow: the KVM agent moves each finalized QCOW2 file to the selected primary storage root and gives it a generated UUID filename:
/mnt/<pool-uuid>/<generated-volume-uuid>
The agent returns the relocated target paths in the cutover answer. The management server persists them in vmware_cbt_migration_disk.target_path through the normal disk-result update path, so no manual database update or schema change is required for this relocation. CloudStack then imports the VM using the flat root-level file name, matching the final placement used by regular OVF/VDDK migrations.
For RBD targets, successful in-place finalization keeps the raw RBD image in place and CloudStack imports it by image name from the selected RBD storage pool. No post-finalization file move is performed, and completed migration deletion remains record-only.
RBD finalization creates only temporary localhost qemu-nbd processes and temporary XML/script files on the conversion host. The wrapper installs a shell trap to stop those bridge processes and remove the PID files after virt-v2v finishes or fails. The persistent storage artifact remains the raw RBD image whose name contains the cloudstack-cbt-<migration-uuid>- marker until CloudStack imports it or cleanup removes it for a failed/cancelled migration.
CloudStack imports finalized CBT disks with the KVM virtio root disk controller. The conversion host must have virtio-win available for Windows guests so that virt-v2v can enable the matching boot driver before the VM is started under KVM. This keeps the persisted rootDiskController detail aligned with the controller model used by the converted guest.
Ceph/RBD support relies on the same KVM host plumbing that normal CloudStack RBD primary storage uses, plus the CBT-specific VMware conversion tools. The selected conversion host must be able to access the destination RBD pool from both Java/libvirt storage code and the qemu command-line tools used by the CBT wrappers.
Required conversion-host capabilities:
CloudStack RBD primary-storage configuration must be valid on the selected KVM/conversion host. For CBT-to-RBD, CloudStack uses the existing KVM storage-pool metadata to build qemu RBD URLs, including monitor addresses, authentication mode, Ceph user, and secret. The CBT qemu path therefore does not rely on /etc/ceph/ceph.conf or a local keyring as its primary credential source when CloudStack supplies explicit RBD URL options.
A local Ceph configuration and keyring can still be useful for operator diagnostics and site-local tooling, for example running ceph -s, rbd ls <pool>, or similar commands without manually passing monitor and authentication options each time. Sites may choose to install those files for operational convenience, but they should not be documented as the required credential source for CBT RBD writes.
The Ceph client packages on every KVM/conversion host should match the Ceph cluster major release, or at least be explicitly supported by that cluster release. Avoid relying on the distribution's stock Ceph packages if they are older than the deployed Ceph cluster. Ancient librbd, librados, qemu RBD block-driver, or Java binding packages can fail in ways that look like CBT errors even though the actual problem is a client/cluster compatibility mismatch.
Practical guidance:
CBT preflight and startVmwareCbtMigration actively probe RBD access when the selected destination pool is RBD. The management server sends the selected conversion host a small probe command using a temporary image named cloudstack-cbt-probe-<uuid>. The KVM agent builds the qemu RBD URL from the existing CloudStack storage-pool metadata, runs qemu-img create, writes and reads a 4 KiB pattern with qemu-io, and removes the temporary image through CloudStack's existing RBD storage adaptor. This catches qemu RBD driver issues, Ceph monitor/authentication problems, and Java RADOS/RBD cleanup failures before the long-running VMware copy starts.
Useful host checks:
ceph -s
ceph osd lspools
rbd ls <pool>
qemu-img --help | grep -i rbd
qemu-io --help | grep -i rbdUseful package/version checks:
ceph --version
rbd --version
ldconfig -p | egrep 'librbd|librados'
java -versionUseful CloudStack database check after the host reconnects:
SELECT h.id, h.name, hd.name, hd.value
FROM cloud.host h
JOIN cloud.host_details hd ON hd.host_id = h.id
WHERE h.name = '<kvm-host-name>'
AND hd.name IN (
'host.vddk.blockcopy.support',
'host.vddk.blockcopy.inplace.finalization.support',
'host.vddk.blockcopy.rbd.support',
'host.vddk.support',
'host.vddk.version',
'host.virtv2v.inplace.version',
'vddk.lib.dir'
)
ORDER BY hd.name;An RBD-capable conversion host should already report VMware CBT capability as true before a migration starts, and the selected destination storage pool must be the RBD pool that the host can access. If these host details are stale after installing packages, restart cloudstack-agent, ensure the management server is running, and wait for host details to be refreshed.
The agent checks these on startup/ready and sends them as host details. Management then persists them into cloud.host_details.
| Host detail | How agent checks it |
|---|---|
| host.virtv2v.version | Runs virt-v2v --version. On Ubuntu/Debian it also checks dpkg -l nbdkit. Version is parsed from virt-v2v --version. |
| vddk.lib.dir | Reads vddk.lib.dir from agent.properties; if blank/invalid, auto-detects with find / -type d -name 'vmware-vix-disklib-distrib' 2>/dev/null | head -n 1. Valid means <dir>/lib64/libvixDiskLib.so* exists. |
| host.vddk.version | Runs nbdkit vddk --dump-plugin libdir=<vddk-lib-dir> and parses vddk_library_version=<n>. |
| host.vddk.support | True only if virt-v2v/nbdkit support is present, VDDK dir is valid, and nbdkit-vddk-plugin can load VDDK via nbdkit vddk --dump-plugin libdir=<dir>. |
| host.qemu.img.version | Runs qemu-img --version, parses first non-empty line. |
| host.qemu.nbd.version | Runs qemu-nbd --version, parses first non-empty line. |
| host.qemu.io.version | Runs qemu-io --version, parses first non-empty line. |
| host.vddk.blockcopy.support | True only if host.vddk.support is true and qemu-img --version, qemu-nbd --version, and qemu-io --version all exit 0. |
| host.vddk.blockcopy.inplace.finalization.support | True only if CBT support is true and either virt-v2v-in-place --version works, or virt-v2v --help 2>&1 | grep -q -- '--in-place' succeeds. |
| host.virtv2v.inplace.version | If virt-v2v-in-place exists, parses virt-v2v-in-place --version. If only virt-v2v --in-place exists, reports the normal virt-v2v version. |
| host.vddk.blockcopy.rbd.support | True only if in-place finalization support is true and qemu-img --help advertises the rbd block driver. |
Important nuance: host.vddk.blockcopy.rbd.support is only the coarse host capability. For an actual selected RBD pool, preflight/start also runs an active probe: create a temporary cloudstack-cbt-probe-<uuid> RBD image, write/read 4 KiB using qemu-io, then delete it through CloudStack's RBD storage adapter. That catches Ceph auth, monitor, qemu RBD, librados/librbd, and Java binding problems.
Windows source VMs also require virtio-win on the selected KVM conversion host. CBT preflight and startVmwareCbtMigration use the same CheckConvertInstanceCommand path as OVF/VDDK import with Windows guest conversion enabled, so a missing virtio-win package is reported before the initial sync starts.
VDDK detection uses either agent configuration or auto-detection. The agent validates the VDDK library by checking that lib64/libvixDiskLib.so* exists and that nbdkit vddk --dump-plugin libdir=<path> reports a library version.
VDDK options can be provided as API details at migration start:
If a value is not provided by the API, the agent uses its configured or detected value. If vddk.thumbprint is not provided, the agent attempts to fetch the vCenter SHA1 certificate thumbprint with openssl.
The implementation does not hard-code one VDDK version. The installed VDDK build must be compatible with the host libraries and pass the agent capability check.
There are two source credential modes:
External credential behavior:
The implementation avoids logging clear-text passwords. As with other CloudStack secret handling, this also depends on callers not placing secrets in unrelated free-form log messages.
CBT migration uses the same eventual import path as the existing OVF/VDDK VM import code. The final CloudStack VM sizing still comes from the selected service offering and any dynamic offering details.
The CBT-specific difference is timing: CBT validates obvious sizing problems early, before the long initial full sync begins. This is meant to avoid spending hours copying disks only to fail final VM import because the selected offering is too small.
The source VM sizing captured during preflight/start includes:
Validation rule:
Validated fields:
Fixed offerings:
Dynamic/custom offerings:
Example custom offering details:
details[0].key=cpuNumber
details[0].value=4
details[1].key=cpuSpeed
details[1].value=2100
details[2].key=memory
details[2].value=4096
This early validation is not intended to be stricter than OVF/VDDK import. It is intended to fail earlier for the same class of sizing mismatch.
The CBT UI is integrated into the Import/Export Instances area.
Implemented UI behavior:
Active states for UI refresh:
The table exposes:
Initial sync progress is currently coarse. While qemu-img convert runs on the agent, management can show the migration state, current step, target path, and disk state, but not a continuously updated percentage. Delta syncs have better post-cycle metrics because changed bytes and dirty rate are returned by the cycle result.
Initial full sync failure:
Delta sync failure:
Cutover finalization failure:
Import failure after successful finalization:
Cancel:
Delete:
Important security choices:
Operational caution:
Relevant unit coverage includes:
The tests cover:
Useful host capability check:
cmk list hosts name=<kvm-host-name> details=all | egrep \
'host.vddk.blockcopy.support|host.vddk.blockcopy.inplace.finalization.support|host.vddk.blockcopy.rbd.support|host.vddk.support|host.vddk.version|host.virtv2v.version|host.virtv2v.inplace.version|host.qemu.img.version|host.qemu.nbd.version|host.qemu.io.version|vddk.lib.dir'Useful VDDK plugin check on the KVM host:
nbdkit vddk --dump-plugin libdir=/opt/vmware-vix-disklib-distrib | \
egrep 'vddk_library_version|vddk_dll|vddk_transport_modes'Useful process check during initial sync:
pgrep -af 'nbdkit|qemu-img|qemu-nbd|nbdcopy'Useful target disk inspection:
qemu-img info /mnt/<pool-uuid>/cloudstack-cbt/<migration-uuid>/<disk>.qcow2| Back | FazBrowse Home | New Git URL |