Skip to content

Commit f84a507

Browse files
committed
restrict pre and post migration commands to only kvm hosts where vm has CLVM/CLVM-NG volumes
1 parent 93782bb commit f84a507

File tree

2 files changed

+49
-46
lines changed

2 files changed

+49
-46
lines changed

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3116,21 +3116,8 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy
31163116

31173117
final VirtualMachineTO to = toVmTO(profile);
31183118

3119-
logger.info("Sending PreMigrationCommand to source host {} for VM {}", srcHostId, vm.getInstanceName());
3120-
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vm.getInstanceName());
3121-
Answer preMigAnswer = null;
3122-
try {
3123-
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
3124-
if (preMigAnswer == null || !preMigAnswer.getResult()) {
3125-
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
3126-
final String msg = "Failed to prepare source host for migration: " + details;
3127-
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vm.getInstanceName(), details);
3128-
throw new CloudRuntimeException(msg);
3129-
}
3130-
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vm.getInstanceName());
3131-
} catch (final AgentUnavailableException | OperationTimedoutException e) {
3132-
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
3133-
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
3119+
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
3120+
executePreMigrationCommand(to, vm.getInstanceName(), srcHostId);
31343121
}
31353122

31363123
final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
@@ -3264,21 +3251,23 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy
32643251
logger.warn("Error while checking the vm {} on host {}", vm, dest.getHost(), e);
32653252
}
32663253
migrated = true;
3267-
try {
3268-
logger.info("Executing post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
3269-
final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName());
3270-
final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand);
3271-
3272-
if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) {
3273-
final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned";
3274-
logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
3275-
vm.getInstanceName(), dstHostId, details);
3276-
} else {
3277-
logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
3254+
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
3255+
try {
3256+
logger.info("Executing post-migration tasks for VM {} with CLVM volumes on destination host {}", vm.getInstanceName(), dstHostId);
3257+
final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName());
3258+
final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand);
3259+
3260+
if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) {
3261+
final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned";
3262+
logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
3263+
vm.getInstanceName(), dstHostId, details);
3264+
} else {
3265+
logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
3266+
}
3267+
} catch (Exception e) {
3268+
logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
3269+
vm.getInstanceName(), dstHostId, e.getMessage(), e);
32783270
}
3279-
} catch (Exception e) {
3280-
logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
3281-
vm.getInstanceName(), dstHostId, e.getMessage(), e);
32823271
}
32833272

32843273
updateClvmLockHostForVmVolumes(vm.getId(), dstHostId);
@@ -4965,21 +4954,8 @@ private void orchestrateMigrateForScale(final String vmUuid, final long srcHostI
49654954

49664955
// Step 1: Send PreMigrationCommand to source host to convert CLVM volumes to shared mode
49674956
// This must happen BEFORE PrepareForMigrationCommand on destination to avoid lock conflicts
4968-
logger.info("Sending PreMigrationCommand to source host {} for VM {}", srcHostId, vm.getInstanceName());
4969-
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vm.getInstanceName());
4970-
Answer preMigAnswer = null;
4971-
try {
4972-
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
4973-
if (preMigAnswer == null || !preMigAnswer.getResult()) {
4974-
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
4975-
final String msg = "Failed to prepare source host for migration: " + details;
4976-
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vm.getInstanceName(), details);
4977-
throw new CloudRuntimeException(msg);
4978-
}
4979-
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vm.getInstanceName());
4980-
} catch (final AgentUnavailableException | OperationTimedoutException e) {
4981-
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
4982-
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
4957+
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
4958+
executePreMigrationCommand(to, vm.getInstanceName(), srcHostId);
49834959
}
49844960

49854961
// Step 2: Send PrepareForMigrationCommand to destination host
@@ -6406,6 +6382,32 @@ private Pair<Long, Long> findClusterAndHostIdForVm(VirtualMachine vm) {
64066382
return findClusterAndHostIdForVm(vm, false);
64076383
}
64086384

6385+
private boolean hasClvmVolumes(long vmId) {
6386+
List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
6387+
return volumes.stream()
6388+
.map(v -> _storagePoolDao.findById(v.getPoolId()))
6389+
.anyMatch(pool -> pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType()));
6390+
}
6391+
6392+
private void executePreMigrationCommand(VirtualMachineTO to, String vmInstanceName, long srcHostId) {
6393+
logger.info("Sending PreMigrationCommand to source host {} for VM {} with CLVM volumes", srcHostId, vmInstanceName);
6394+
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vmInstanceName);
6395+
Answer preMigAnswer = null;
6396+
try {
6397+
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
6398+
if (preMigAnswer == null || !preMigAnswer.getResult()) {
6399+
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
6400+
final String msg = "Failed to prepare source host for migration: " + details;
6401+
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vmInstanceName, details);
6402+
throw new CloudRuntimeException(msg);
6403+
}
6404+
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vmInstanceName);
6405+
} catch (final AgentUnavailableException | OperationTimedoutException e) {
6406+
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
6407+
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
6408+
}
6409+
}
6410+
64096411
@Override
64106412
public Pair<Long, Long> findClusterAndHostIdForVm(long vmId) {
64116413
VMInstanceVO vm = _vmDao.findById(vmId);

engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,8 +2233,7 @@ private void prepareDisksForMigrationForClvm(VirtualMachineTO vmTO, Map<VolumeIn
22332233
boolean hasClvmSource = volumeDataStoreMap.keySet().stream()
22342234
.map(v -> _storagePoolDao.findById(v.getPoolId()))
22352235
.anyMatch(p -> p != null && (p.getPoolType() == StoragePoolType.CLVM || p.getPoolType() == StoragePoolType.CLVM_NG));
2236-
2237-
if (hasClvmSource) {
2236+
if (hasClvmSource && srcHost.getHypervisorType() == HypervisorType.KVM) {
22382237
logger.info("CLVM/CLVM_NG source pool detected for VM [{}], sending PreMigrationCommand to source host [{}] to convert volumes to shared mode.", vmTO.getName(), srcHost.getId());
22392238
PreMigrationCommand preMigCmd = new PreMigrationCommand(vmTO, vmTO.getName());
22402239
try {
@@ -2248,6 +2247,8 @@ private void prepareDisksForMigrationForClvm(VirtualMachineTO vmTO, Map<VolumeIn
22482247
} catch (Exception e) {
22492248
logger.warn("Failed to send PreMigrationCommand to source host [{}] for VM [{}]: {}. Migration will continue but may fail if volumes are exclusively locked.", srcHost.getId(), vmTO.getName(), e.getMessage());
22502249
}
2250+
} else if (hasClvmSource) {
2251+
logger.debug("Skipping PreMigrationCommand for non-KVM hypervisor type: {} on host [{}]", srcHost.getHypervisorType(), srcHost.getId());
22512252
}
22522253
}
22532254

0 commit comments

Comments
 (0)