Search in sources :

Example 1 with BlockJobListener

use of org.libvirt.event.BlockJobListener 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;
    List<LibvirtDiskDef> disks;
    Domain dm = null;
    Connect conn = null;
    String currentVolumePath;
    String newVolumePath;
    CountDownLatch completeSignal = new CountDownLatch(1);
    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 (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();
            disk.setDiskPath(newVolumePath);
            logger.debug("Starting block copy for domain " + dm.getName() + " from " + currentVolumePath + " to " + newVolumePath);
            dm.blockCopy(currentVolumePath, disk.toString(), new DomainBlockCopyParameters(), 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());
        StoragePool storagePool = conn.storagePoolLookupByUUIDString(command.getPool().getUuid());
        storagePool.refresh(0);
        logger.debug("Cleaning up old disk " + currentVolumePath);
        StorageVol storageVol = conn.storageVolLookupByPath(currentVolumePath);
        storageVol.delete(0);
    } 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);
        }
    }
    return new MigrateVolumeAnswer(command, result == null, result, command.getVolumePath());
}
Also used : LibvirtException(org.libvirt.LibvirtException) StoragePool(org.libvirt.StoragePool) StorageVol(org.libvirt.StorageVol) Connect(org.libvirt.Connect) CountDownLatch(java.util.concurrent.CountDownLatch) DomainBlockCopyParameters(org.libvirt.parameters.DomainBlockCopyParameters) LibvirtDiskDef(com.cloud.hypervisor.kvm.resource.xml.LibvirtDiskDef) MigrateVolumeAnswer(com.cloud.agent.api.storage.MigrateVolumeAnswer) BlockJobListener(org.libvirt.event.BlockJobListener) Domain(org.libvirt.Domain)

Aggregations

MigrateVolumeAnswer (com.cloud.agent.api.storage.MigrateVolumeAnswer)1 LibvirtDiskDef (com.cloud.hypervisor.kvm.resource.xml.LibvirtDiskDef)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Connect (org.libvirt.Connect)1 Domain (org.libvirt.Domain)1 LibvirtException (org.libvirt.LibvirtException)1 StoragePool (org.libvirt.StoragePool)1 StorageVol (org.libvirt.StorageVol)1 BlockJobListener (org.libvirt.event.BlockJobListener)1 DomainBlockCopyParameters (org.libvirt.parameters.DomainBlockCopyParameters)1