use of com.cloud.legacymodel.communication.answer.MigrateVolumeAnswer in project cosmic by MissionCriticalCloud.
the class LibvirtMigrateVolumeCommandWrapper method execute.
@Override
public Answer execute(final MigrateVolumeCommand command, final LibvirtComputingResource libvirtComputingResource) {
String result = null;
final String vmName = command.getAttachedVmName();
LibvirtDiskDef disk = null;
final List<LibvirtDiskDef> disks;
boolean isMigrationSuccessfull = false;
Domain dm = null;
Connect conn = null;
String currentVolumePath = null;
final String newVolumePath;
final CountDownLatch completeSignal = new CountDownLatch(1);
final BlockJobListener blockJobListener = new BlockJobListener() {
@Override
public void onBlockJobCompleted(final Domain domain, final String disk, final int type) throws LibvirtException {
onBlockJobReady(domain, disk, type);
}
@Override
public void onBlockJobFailed(final Domain domain, final String disk, final int type) throws LibvirtException {
throw new LibvirtException("BlockJobFailed");
}
@Override
public void onBlockJobCanceled(final Domain domain, final String disk, final int type) throws LibvirtException {
throw new LibvirtException("BlockJobCanceled");
}
@Override
public void onBlockJobReady(final Domain domain, final String disk, final int type) throws LibvirtException {
domain.blockJobAbort(disk, DomainBlockJobAbortFlags.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT);
completeSignal.countDown();
}
};
try {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
disks = libvirtComputingResource.getDisks(conn, vmName);
dm = conn.domainLookupByName(vmName);
newVolumePath = "/mnt/" + command.getPool().getUuid() + "/" + command.getVolumePath();
for (final LibvirtDiskDef diskDef : disks) {
if (diskDef.getDiskPath().contains(command.getVolumePath())) {
disk = diskDef;
break;
}
}
logger.debug("Registering block job listener with libvirt for domain " + dm.getName());
dm.addBlockJobListener(blockJobListener);
if (disk != null) {
currentVolumePath = disk.getDiskPath();
int blockCopySpeed = libvirtComputingResource.getVmBlockCopySpeed();
disk.setDiskPath(newVolumePath);
DomainBlockCopyParameters domainBlockCopyParameters = new DomainBlockCopyParameters();
domainBlockCopyParameters.setDomainBlockCopyBandwidth(blockCopySpeed);
String scale = new String(domainBlockCopyParameters.isDomainBlockCopyBytes() ? " Bytes/s" : " MiB/s");
logger.debug("Starting block copy for domain " + dm.getName() + " from " + currentVolumePath + " to " + newVolumePath + " @ " + blockCopySpeed + scale);
dm.blockCopy(currentVolumePath, disk.toString(), domainBlockCopyParameters.getTypedParameters(), 0);
} else {
throw new LibvirtException("Couldn't find disk: " + command.getVolumePath() + " on vm: " + dm.getName());
}
logger.debug("Waiting for block copy for domain " + dm.getName() + " from " + currentVolumePath + " to " + newVolumePath + " to finish");
completeSignal.await();
logger.debug("Refreshing storage pool " + command.getPool().getUuid());
final StoragePool storagePool = conn.storagePoolLookupByUUIDString(command.getPool().getUuid());
storagePool.refresh(0);
isMigrationSuccessfull = true;
} catch (final LibvirtException | InterruptedException e) {
logger.debug("Can't migrate disk: " + e.getMessage());
result = e.getMessage();
} finally {
try {
if (dm != null) {
dm.free();
}
// Stop block job listener
if (conn != null) {
conn.removeBlockJobListener(blockJobListener);
}
} catch (final LibvirtException e) {
logger.debug("Ignoring libvirt error.", e);
}
}
try {
if (isMigrationSuccessfull && conn != null) {
logger.debug("Cleaning up old disk " + currentVolumePath);
final StorageVol storageVol = conn.storageVolLookupByPath(currentVolumePath);
storageVol.delete(0);
}
} catch (final LibvirtException e) {
logger.error("Cleaning up old disk " + currentVolumePath + " failed!", e);
}
return new MigrateVolumeAnswer(command, result == null, result, command.getVolumePath());
}
use of com.cloud.legacymodel.communication.answer.MigrateVolumeAnswer in project cosmic by MissionCriticalCloud.
the class AncientDataMotionStrategy method migrateVolumeToPool.
protected Answer migrateVolumeToPool(final DataObject srcData, final DataObject destData) {
final String value = configDao.getValue(Config.MigrateWait.key());
final int waitInterval = NumbersUtil.parseInt(value, Integer.parseInt(Config.MigrateWait.getDefaultValue()));
final VolumeInfo volume = (VolumeInfo) srcData;
final StoragePool destPool = (StoragePool) dataStoreMgr.getDataStore(destData.getDataStore().getId(), DataStoreRole.Primary);
final MigrateVolumeCommand command = new MigrateVolumeCommand(volume.getId(), volume.getPath(), destPool, volume.getAttachedVmName(), volume.getVolumeType(), waitInterval);
final EndPoint ep = selector.select(srcData, StorageAction.MIGRATEVOLUME);
Answer answer = null;
if (ep == null) {
final String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(command, false, errMsg);
} else {
answer = ep.sendMessage(command);
}
if (answer == null || !answer.getResult()) {
throw new CloudRuntimeException("Failed to migrate volume " + volume + " to storage pool " + destPool);
} else {
// Update the volume details after migration.
final VolumeVO volumeVo = volDao.findById(volume.getId());
final Long oldPoolId = volume.getPoolId();
volumeVo.setPath(((MigrateVolumeAnswer) answer).getVolumePath());
final String chainInfo = ((MigrateVolumeAnswer) answer).getVolumeChainInfo();
if (chainInfo != null) {
volumeVo.setChainInfo(chainInfo);
}
volumeVo.setPodId(destPool.getPodId());
volumeVo.setPoolId(destPool.getId());
volumeVo.setLastPoolId(oldPoolId);
// For SMB, pool credentials are also stored in the uri query string. We trim the query string
// part here to make sure the credentials do not get stored in the db unencrypted.
String folder = destPool.getPath();
if (destPool.getPoolType() == StoragePoolType.SMB && folder != null && folder.contains("?")) {
folder = folder.substring(0, folder.indexOf("?"));
}
volumeVo.setFolder(folder);
volDao.update(volume.getId(), volumeVo);
}
return answer;
}
use of com.cloud.legacymodel.communication.answer.MigrateVolumeAnswer in project cosmic by MissionCriticalCloud.
the class XenServer610MigrateVolumeCommandWrapper method execute.
@Override
public Answer execute(final MigrateVolumeCommand command, final XenServer610Resource xenServer610Resource) {
final Connection connection = xenServer610Resource.getConnection();
final String volumeUUID = command.getVolumePath();
final StorageFilerTO poolTO = command.getPool();
try {
final String uuid = poolTO.getUuid();
final SR destinationPool = xenServer610Resource.getStorageRepository(connection, uuid);
final VDI srcVolume = xenServer610Resource.getVDIbyUuid(connection, volumeUUID);
final Map<String, String> other = new HashMap<>();
other.put("live", "true");
// Live migrate the vdi across pool.
final Task task = srcVolume.poolMigrateAsync(connection, destinationPool, other);
final long timeout = xenServer610Resource.getMigrateWait() * 1000L;
xenServer610Resource.waitForTask(connection, task, 1000, timeout);
xenServer610Resource.checkForSuccess(connection, task);
final VDI dvdi = Types.toVDI(task, connection);
return new MigrateVolumeAnswer(command, true, null, dvdi.getUuid(connection));
} catch (final Exception e) {
final String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString();
s_logger.error(msg, e);
return new MigrateVolumeAnswer(command, false, msg, null);
}
}
Aggregations