Skip to content

Commit

Permalink
core: Add support for zero-copy migrations
Browse files Browse the repository at this point in the history
Zero-copy migrations help with migrating very large VMs (>1 TB) or
busy large VMs.

Zero-copy migrations are added using a new migration policy.  Since it
is a new feature, there may be unanticipated problems so the policy is
supposed to be used only when the already available migration policies
are insufficient to migrate a VM and the user is willing to accept the
risk.

Zero-copy can be used only with parallel migrations so it requires
parallel migrations enabled in Engine config.  If they are disabled in
VM/cluster configuration, they are still used if the zero-copy policy
is enabled.

Zero-copy migrations cannot be currently used with encrypted
migrations.  If encrypted migrations are requested, the given policy
can still be used but zero-copy is disabled.

The policy uses longer downtimes since it is aimed at very large VMs
and it is unlikely that short downtimes are any useful for such VMs.

It is supposed that Vdsm on the host supports zero-copy migrations,
since they are used only when parallel migrations are enabled,
i.e. with cluster version 4.7 by default, and it is supposed that the
hosts run an up-to-date OS.  If the host doesn’t support zero-copy
migrations then migration API violation will be logged there and
zero-copy won’t be enabled for the migration.

See also
https://ovirt.org/develop/release-management/features/virt/zerocopy-migrations.html.

Bug-Url: https://bugzilla.redhat.com/2089434
  • Loading branch information
mz-pdm committed Sep 6, 2022
1 parent 0a8fdc3 commit 6e1f44c
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -405,19 +405,22 @@ private MigrateVDSCommandParameters createMigrateVDSCommandParameters() {
Integer maxBandwidth = null;

Boolean autoConverge = getAutoConverge();
Integer parallelMigrations = getParallelMigrations();
Boolean migrateCompressed = parallelMigrations == null ? getMigrateCompressed() : false;
Boolean migrateEncrypted = vmHandler.getMigrateEncrypted(getVm(), getCluster());
Boolean enableGuestEvents = null;
MigrationPolicy clusterMigrationPolicy = convergenceConfigProvider.getMigrationPolicy(
getCluster().getMigrationPolicyId(),
getCluster().getCompatibilityVersion());
MigrationPolicy effectiveMigrationPolicy = findEffectiveConvergenceConfig(clusterMigrationPolicy);
boolean zeroCopy = effectiveMigrationPolicy.isZeroCopy()
&& FeatureSupported.isParallelMigrationsSupported(getVm().getCompatibilityVersion())
&& !migrateEncrypted;
Integer parallelMigrations = getParallelMigrations(zeroCopy);
Boolean migrateCompressed = parallelMigrations == null ? getMigrateCompressed() : false;
Integer maxIncomingMigrations = 1;
Integer maxOutgoingMigrations = 1;
List<String> cpuSets = null;
List<String> numaNodeSets = null;

MigrationPolicy clusterMigrationPolicy = convergenceConfigProvider.getMigrationPolicy(
getCluster().getMigrationPolicyId(),
getCluster().getCompatibilityVersion());
MigrationPolicy effectiveMigrationPolicy = findEffectiveConvergenceConfig(clusterMigrationPolicy);
ConvergenceConfig convergenceConfig = getVm().getStatus() == VMStatus.Paused || parallelMigrations != null
? filterOutPostcopy(effectiveMigrationPolicy.getConfig())
: effectiveMigrationPolicy.getConfig();
Expand Down Expand Up @@ -463,6 +466,7 @@ private MigrateVDSCommandParameters createMigrateVDSCommandParameters() {
getDestinationVds().getConsoleAddress(),
maxBandwidth,
parallelMigrations,
zeroCopy,
convergenceSchedule,
enableGuestEvents,
maxIncomingMigrations,
Expand Down Expand Up @@ -572,14 +576,19 @@ private Integer getLinkSpeedBandwidth(Guid hostId) {
}

/**
* @param enforce If true then use parallel migration even if they would be normally disabled.
* @return Number of parallel migrations to use in this migration or `null` to
* not use parallel migrations.
*/
private Integer getParallelMigrations() {
private Integer getParallelMigrations(boolean enforce) {
if (!FeatureSupported.isParallelMigrationsSupported(getVm().getCompatibilityVersion())) {
return null;
}
Integer parallelMigrationsRequested = getParallelMigrationsFromVmOrCluster();
if (enforce && (parallelMigrationsRequested == ParallelMigrationsType.DISABLED.getValue()
|| parallelMigrationsRequested == ParallelMigrationsType.AUTO.getValue())) {
parallelMigrationsRequested = ParallelMigrationsType.AUTO_PARALLEL.getValue();
}
Integer parallelMigrations = parallelMigrationsRequested;
if (parallelMigrationsRequested == ParallelMigrationsType.AUTO.getValue()
|| parallelMigrationsRequested == ParallelMigrationsType.AUTO_PARALLEL.getValue()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class MigrationPolicy implements Serializable, Nameable {

private boolean enableGuestEvents;

private boolean zeroCopy;

private ConvergenceConfig config;

public MigrationPolicy() {}
Expand Down Expand Up @@ -95,4 +97,12 @@ public boolean isEnableGuestEvents() {
public void setEnableGuestEvents(boolean enableGuestEvents) {
this.enableGuestEvents = enableGuestEvents;
}

public boolean isZeroCopy() {
return zeroCopy;
}

public void setZeroCopy(boolean zeroCopy) {
this.zeroCopy = zeroCopy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class MigrateVDSCommandParameters extends VdsAndVmIDVDSParametersBase {
private String consoleAddress;
private Integer maxBandwidth;
private Integer parallelMigrations;
private boolean zeroCopy;
private Boolean enableGuestEvents;
private Integer maxIncomingMigrations;
private Integer maxOutgoingMigrations;
Expand All @@ -34,7 +35,7 @@ public class MigrateVDSCommandParameters extends VdsAndVmIDVDSParametersBase {
public MigrateVDSCommandParameters(Guid vdsId, Guid vmId, String srcHost, Guid dstVdsId, String dstHost,
MigrationMethod migrationMethod, boolean tunnelMigration, String dstQemu, Version clusterVersion,
int migrationDowntime, Boolean autoConverge, Boolean migrateCompressed, Boolean migrateEncrypted,
String consoleAddress, Integer maxBandwidth, Integer parallelMigrations,
String consoleAddress, Integer maxBandwidth, Integer parallelMigrations, boolean zeroCopy,
Map<String, Object> convergenceSchedule, Boolean enableGuestEvents, Integer maxIncomingMigrations,
Integer maxOutgoingMigrations, List<String> cpuSets, List<String> numaNodeSets) {
super(vdsId, vmId);
Expand All @@ -52,6 +53,7 @@ public MigrateVDSCommandParameters(Guid vdsId, Guid vmId, String srcHost, Guid d
this.consoleAddress = consoleAddress;
this.maxBandwidth = maxBandwidth;
this.parallelMigrations = parallelMigrations;
this.zeroCopy = zeroCopy;
this.convergenceSchedule = convergenceSchedule;
this.enableGuestEvents = enableGuestEvents;
this.maxIncomingMigrations = maxIncomingMigrations;
Expand Down Expand Up @@ -156,6 +158,14 @@ public void setParallelMigrations(Integer parallelMigrations) {
this.parallelMigrations = parallelMigrations;
}

public boolean isZeroCopy() {
return zeroCopy;
}

public void setZeroCopy(boolean zeroCopy) {
this.zeroCopy = zeroCopy;
}

public Boolean isEnableGuestEvents() {
return enableGuestEvents;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ private Map<String, Object> createMigrationInfo() {
migrationInfo.put(VdsProperties.PARALLEL_MIGRATION_CONNECTIONS, parameters.getParallelMigrations());
}

if (parameters.isZeroCopy()) {
migrationInfo.put(VdsProperties.MIGRATION_ZEROCOPY, parameters.isZeroCopy());
}

if (parameters.getConvergenceSchedule() != null) {
migrationInfo.put(VdsProperties.MIGRATION_CONVERGENCE_SCHEDULE, parameters.getConvergenceSchedule());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ public final class VdsProperties {
public static final String ENABLE_GUEST_EVENTS = "enableGuestEvents";
public static final String MIGRATION_BANDWIDTH = "maxBandwidth";
public static final String PARALLEL_MIGRATION_CONNECTIONS = "parallel";
public static final String MIGRATION_ZEROCOPY = "zerocopy";
public static final String MIGRATION_INIT_STEPS = "init";
public static final String MIGRATION_STALLING_STEPS = "stalling";
public static final String MIGRATION_SOURCE = "Migration Source";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.ovirt.engine.core.common.businessentities.AdditionalFeature;
import org.ovirt.engine.core.common.businessentities.ArchitectureType;
Expand Down Expand Up @@ -1523,6 +1524,9 @@ public void refreshMigrationPolicies() {
}

List<MigrationPolicy> policies = AsyncDataProvider.getInstance().getMigrationPolicies(version);
if (version == null || !AsyncDataProvider.getInstance().isParallelMigrationsSupportedByVersion(version)) {
policies = policies.stream().filter(policy -> !policy.isZeroCopy()).collect(Collectors.toList());
}
getMigrationPolicies().setItems(policies);

MigrationPolicy migrationPolicy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3855,6 +3855,9 @@ private void refreshMigrationPolicies() {
}

List<MigrationPolicy> policies = AsyncDataProvider.getInstance().getMigrationPolicies(version);
if (version == null || !AsyncDataProvider.getInstance().isParallelMigrationsSupportedByVersion(version)) {
policies = policies.stream().filter(policy -> !policy.isZeroCopy()).collect(Collectors.toList());
}

Guid clusterMigrationPolicyID = selectedCluster.getMigrationPolicyId();
for (MigrationPolicy policy : policies) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ public interface LocalizedMigrationPolicies extends ConstantsWithLookup {
String name_a7aeedb2_8d66_4e51_bb22_32595027ce71();

String description_a7aeedb2_8d66_4e51_bb22_32595027ce71();

String name_57237b82_b8c2_425f_b425_114b35219626();

String description_57237b82_b8c2_425f_b425_114b35219626();
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ description_80554327_0569_496b_bdeb_fcbbf52b827b=A policy that lets the VM migra
name_80554327_0569_496b_bdeb_fcbbf52b827c=Suspend workload if needed
description_80554327_0569_496b_bdeb_fcbbf52b827c=A policy that lets the VM migrate in most situations, including VMs running heavy workloads. On the other hand, the VM may experience a more significant downtime. The migration may still be aborted for extreme workloads. The guest agent hook mechanism is enabled.
name_a7aeedb2_8d66_4e51_bb22_32595027ce71=Post-copy migration
description_a7aeedb2_8d66_4e51_bb22_32595027ce71=The VM should not experience any significant downtime. If the VM migration is not converging for a long time, the migration will be switched to post-copy. The guest agent hook mechanism is enabled.
description_a7aeedb2_8d66_4e51_bb22_32595027ce71=The VM should not experience any significant downtime. If the VM migration is not converging for a long time, the migration will be switched to post-copy. The guest agent hook mechanism is enabled.
name_57237b82_b8c2_425f_b425_114b35219626=Very large VMs
description_57237b82_b8c2_425f_b425_114b35219626=The VM cannot be migrated using any of the other policies, a possibly risky migration mechanism is accepted and the migration need not be encrypted. The VM may experience a significant downtime. The migration may still be aborted if it cannot converge. The guest agent hook mechanism is enabled.
Loading

0 comments on commit 6e1f44c

Please sign in to comment.