mirror of https://github.com/apache/cloudstack.git
restrict pre and post migration commands to only kvm hosts where vm has CLVM/CLVM-NG volumes
This commit is contained in:
parent
93782bb5f1
commit
f84a507224
|
|
@ -3116,21 +3116,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final VirtualMachineTO to = toVmTO(profile);
|
||||
|
||||
logger.info("Sending PreMigrationCommand to source host {} for VM {}", srcHostId, vm.getInstanceName());
|
||||
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vm.getInstanceName());
|
||||
Answer preMigAnswer = null;
|
||||
try {
|
||||
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
|
||||
if (preMigAnswer == null || !preMigAnswer.getResult()) {
|
||||
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
|
||||
final String msg = "Failed to prepare source host for migration: " + details;
|
||||
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vm.getInstanceName(), details);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vm.getInstanceName());
|
||||
} catch (final AgentUnavailableException | OperationTimedoutException e) {
|
||||
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
|
||||
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
|
||||
executePreMigrationCommand(to, vm.getInstanceName(), srcHostId);
|
||||
}
|
||||
|
||||
final PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);
|
||||
|
|
@ -3264,21 +3251,23 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
logger.warn("Error while checking the vm {} on host {}", vm, dest.getHost(), e);
|
||||
}
|
||||
migrated = true;
|
||||
try {
|
||||
logger.info("Executing post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
|
||||
final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName());
|
||||
final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand);
|
||||
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
|
||||
try {
|
||||
logger.info("Executing post-migration tasks for VM {} with CLVM volumes on destination host {}", vm.getInstanceName(), dstHostId);
|
||||
final PostMigrationCommand postMigrationCommand = new PostMigrationCommand(to, vm.getInstanceName());
|
||||
final Answer postMigrationAnswer = _agentMgr.send(dstHostId, postMigrationCommand);
|
||||
|
||||
if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) {
|
||||
final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned";
|
||||
logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
|
||||
vm.getInstanceName(), dstHostId, details);
|
||||
} else {
|
||||
logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
|
||||
if (postMigrationAnswer == null || !postMigrationAnswer.getResult()) {
|
||||
final String details = postMigrationAnswer != null ? postMigrationAnswer.getDetails() : "null answer returned";
|
||||
logger.warn("Post-migration tasks failed for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
|
||||
vm.getInstanceName(), dstHostId, details);
|
||||
} else {
|
||||
logger.info("Successfully completed post-migration tasks for VM {} on destination host {}", vm.getInstanceName(), dstHostId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
|
||||
vm.getInstanceName(), dstHostId, e.getMessage(), e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Exception during post-migration tasks for VM {} on destination host {}: {}. Migration completed but some cleanup may be needed.",
|
||||
vm.getInstanceName(), dstHostId, e.getMessage(), e);
|
||||
}
|
||||
|
||||
updateClvmLockHostForVmVolumes(vm.getId(), dstHostId);
|
||||
|
|
@ -4965,21 +4954,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
// Step 1: Send PreMigrationCommand to source host to convert CLVM volumes to shared mode
|
||||
// This must happen BEFORE PrepareForMigrationCommand on destination to avoid lock conflicts
|
||||
logger.info("Sending PreMigrationCommand to source host {} for VM {}", srcHostId, vm.getInstanceName());
|
||||
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vm.getInstanceName());
|
||||
Answer preMigAnswer = null;
|
||||
try {
|
||||
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
|
||||
if (preMigAnswer == null || !preMigAnswer.getResult()) {
|
||||
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
|
||||
final String msg = "Failed to prepare source host for migration: " + details;
|
||||
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vm.getInstanceName(), details);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vm.getInstanceName());
|
||||
} catch (final AgentUnavailableException | OperationTimedoutException e) {
|
||||
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
|
||||
if (vm.getHypervisorType() == HypervisorType.KVM && hasClvmVolumes(vm.getId())) {
|
||||
executePreMigrationCommand(to, vm.getInstanceName(), srcHostId);
|
||||
}
|
||||
|
||||
// Step 2: Send PrepareForMigrationCommand to destination host
|
||||
|
|
@ -6406,6 +6382,32 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return findClusterAndHostIdForVm(vm, false);
|
||||
}
|
||||
|
||||
private boolean hasClvmVolumes(long vmId) {
|
||||
List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
|
||||
return volumes.stream()
|
||||
.map(v -> _storagePoolDao.findById(v.getPoolId()))
|
||||
.anyMatch(pool -> pool != null && ClvmLockManager.isClvmPoolType(pool.getPoolType()));
|
||||
}
|
||||
|
||||
private void executePreMigrationCommand(VirtualMachineTO to, String vmInstanceName, long srcHostId) {
|
||||
logger.info("Sending PreMigrationCommand to source host {} for VM {} with CLVM volumes", srcHostId, vmInstanceName);
|
||||
final PreMigrationCommand preMigCmd = new PreMigrationCommand(to, vmInstanceName);
|
||||
Answer preMigAnswer = null;
|
||||
try {
|
||||
preMigAnswer = _agentMgr.send(srcHostId, preMigCmd);
|
||||
if (preMigAnswer == null || !preMigAnswer.getResult()) {
|
||||
final String details = preMigAnswer != null ? preMigAnswer.getDetails() : "null answer returned";
|
||||
final String msg = "Failed to prepare source host for migration: " + details;
|
||||
logger.error("Failed to prepare source host {} for migration of VM {}: {}", srcHostId, vmInstanceName, details);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
logger.info("Successfully prepared source host {} for migration of VM {}", srcHostId, vmInstanceName);
|
||||
} catch (final AgentUnavailableException | OperationTimedoutException e) {
|
||||
logger.error("Failed to send PreMigrationCommand to source host {}: {}", srcHostId, e.getMessage(), e);
|
||||
throw new CloudRuntimeException("Failed to prepare source host for migration: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<Long, Long> findClusterAndHostIdForVm(long vmId) {
|
||||
VMInstanceVO vm = _vmDao.findById(vmId);
|
||||
|
|
|
|||
|
|
@ -2233,8 +2233,7 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||
boolean hasClvmSource = volumeDataStoreMap.keySet().stream()
|
||||
.map(v -> _storagePoolDao.findById(v.getPoolId()))
|
||||
.anyMatch(p -> p != null && (p.getPoolType() == StoragePoolType.CLVM || p.getPoolType() == StoragePoolType.CLVM_NG));
|
||||
|
||||
if (hasClvmSource) {
|
||||
if (hasClvmSource && srcHost.getHypervisorType() == HypervisorType.KVM) {
|
||||
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());
|
||||
PreMigrationCommand preMigCmd = new PreMigrationCommand(vmTO, vmTO.getName());
|
||||
try {
|
||||
|
|
@ -2248,6 +2247,8 @@ public class StorageSystemDataMotionStrategy implements DataMotionStrategy {
|
|||
} catch (Exception e) {
|
||||
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());
|
||||
}
|
||||
} else if (hasClvmSource) {
|
||||
logger.debug("Skipping PreMigrationCommand for non-KVM hypervisor type: {} on host [{}]", srcHost.getHypervisorType(), srcHost.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue