Search in sources :

Example 11 with VifDriver

use of com.cloud.agent.resource.kvm.vif.VifDriver in project cosmic by MissionCriticalCloud.

the class LibvirtStopCommandWrapper method execute.

@Override
public Answer execute(final StopCommand command, final LibvirtComputingResource libvirtComputingResource) {
    final String vmName = command.getVmName();
    final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
    if (command.checkBeforeCleanup()) {
        try {
            final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
            final Domain vm = conn.domainLookupByName(command.getVmName());
            if (vm != null && vm.getInfo().state == DomainState.VIR_DOMAIN_RUNNING) {
                return new StopAnswer(command, "vm is still running on host", false);
            }
        } catch (final Exception e) {
            s_logger.debug("Failed to get vm status in case of checkboforecleanup is true", e);
        }
    }
    try {
        final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
        final List<LibvirtDiskDef> disks = libvirtComputingResource.getDisks(conn, vmName);
        final List<LibvirtVmDef.InterfaceDef> ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
        final String result = libvirtComputingResource.stopVm(conn, vmName, command.isForceStop());
        if (result == null) {
            for (final LibvirtDiskDef disk : disks) {
                libvirtComputingResource.cleanupDisk(disk);
            }
            for (final LibvirtVmDef.InterfaceDef iface : ifaces) {
                // each interface at this point, so inform all vif drivers
                for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
                    vifDriver.unplug(iface);
                }
            }
        }
        return new StopAnswer(command, result, true);
    } catch (final LibvirtException e) {
        return new StopAnswer(command, e.getMessage(), false);
    }
}
Also used : LibvirtVmDef(com.cloud.agent.resource.kvm.xml.LibvirtVmDef) LibvirtException(org.libvirt.LibvirtException) Connect(org.libvirt.Connect) LibvirtException(org.libvirt.LibvirtException) VifDriver(com.cloud.agent.resource.kvm.vif.VifDriver) LibvirtDiskDef(com.cloud.agent.resource.kvm.xml.LibvirtDiskDef) Domain(org.libvirt.Domain) StopAnswer(com.cloud.legacymodel.communication.answer.StopAnswer)

Example 12 with VifDriver

use of com.cloud.agent.resource.kvm.vif.VifDriver in project cosmic by MissionCriticalCloud.

the class LibvirtUnPlugNicCommandWrapper method execute.

@Override
public Answer execute(final UnPlugNicCommand command, final LibvirtComputingResource libvirtComputingResource) {
    final NicTO nic = command.getNic();
    final String vmName = command.getVmName();
    Domain vm = null;
    try {
        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
        final Connect conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
        vm = libvirtComputingResource.getDomain(conn, vmName);
        final List<LibvirtVmDef.InterfaceDef> pluggedNics = libvirtComputingResource.getInterfaces(conn, vmName);
        for (final LibvirtVmDef.InterfaceDef pluggedNic : pluggedNics) {
            if (pluggedNic.getMacAddress().equalsIgnoreCase(nic.getMac())) {
                vm.detachDevice(pluggedNic.toString());
                // each interface at this point, so inform all vif drivers
                for (final VifDriver vifDriver : libvirtComputingResource.getAllVifDrivers()) {
                    vifDriver.unplug(pluggedNic);
                }
                return new UnPlugNicAnswer(command, true, "success");
            }
        }
        return new UnPlugNicAnswer(command, true, "success");
    } catch (final LibvirtException e) {
        final String msg = " Unplug Nic failed due to " + e.toString();
        s_logger.warn(msg, e);
        return new UnPlugNicAnswer(command, false, msg);
    } finally {
        if (vm != null) {
            try {
                vm.free();
            } catch (final LibvirtException l) {
                s_logger.trace("Ignoring libvirt error.", l);
            }
        }
    }
}
Also used : LibvirtVmDef(com.cloud.agent.resource.kvm.xml.LibvirtVmDef) LibvirtException(org.libvirt.LibvirtException) UnPlugNicAnswer(com.cloud.legacymodel.communication.answer.UnPlugNicAnswer) Connect(org.libvirt.Connect) Domain(org.libvirt.Domain) VifDriver(com.cloud.agent.resource.kvm.vif.VifDriver) NicTO(com.cloud.legacymodel.to.NicTO)

Example 13 with VifDriver

use of com.cloud.agent.resource.kvm.vif.VifDriver in project cosmic by MissionCriticalCloud.

the class LibvirtMigrateCommandWrapper method execute.

@Override
public Answer execute(final MigrateCommand command, final LibvirtComputingResource libvirtComputingResource) {
    final String vmName = command.getVmName();
    String result = null;
    List<LibvirtVmDef.InterfaceDef> ifaces = null;
    final List<LibvirtDiskDef> disks;
    Domain dm = null;
    Connect dconn = null;
    Domain destDomain = null;
    Connect conn = null;
    final String xmlDesc;
    List<Ternary<String, Boolean, String>> vmsnapshots = null;
    try {
        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
        conn = libvirtUtilitiesHelper.getConnectionByVmName(vmName);
        ifaces = libvirtComputingResource.getInterfaces(conn, vmName);
        disks = libvirtComputingResource.getDisks(conn, vmName);
        dm = conn.domainLookupByName(vmName);
        /*
             * We replace the private IP address with the address of the destination host. This is because the VNC listens on
             * the private IP address of the hypervisor, but that address is ofcourse different on the target host.
             *
             * MigrateCommand.getDestinationIp() returns the private IP address of the target hypervisor. So it's safe to use.
             *
             * The Domain.migrate method from libvirt supports passing a different XML description for the instance to be used
             * on the target host.
             *
             * This is supported by libvirt-java from version 0.50.0
             *
             * CVE-2015-3252: Get XML with sensitive information suitable for migration by using VIR_DOMAIN_XML_MIGRATABLE
             * flag (value = 8) https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainXMLFlags
             *
             * Use VIR_DOMAIN_XML_SECURE (value = 1) prior to v1.0.0.
             */
        // 1000000 equals v1.0.0
        final int xmlFlag = conn.getLibVirVersion() >= 1000000 ? 8 : 1;
        xmlDesc = dm.getXMLDesc(xmlFlag).replace(libvirtComputingResource.getPrivateIp(), command.getDestinationIp());
        // delete the metadata of vm snapshots before migration
        vmsnapshots = libvirtComputingResource.cleanVMSnapshotMetadata(dm);
        dconn = libvirtUtilitiesHelper.retrieveQemuConnection("qemu+tcp://" + command.getDestinationIp() + "/system");
        // run migration in thread so we can monitor it
        s_logger.info("Live migration of instance " + vmName + " initiated");
        final ExecutorService executor = Executors.newFixedThreadPool(1);
        final Callable<Domain> worker = new MigrateKvmAsync(libvirtComputingResource, dm, dconn, xmlDesc, vmName, command.getDestinationIp());
        final Future<Domain> migrateThread = executor.submit(worker);
        executor.shutdown();
        long sleeptime = 0;
        while (!executor.isTerminated()) {
            Thread.sleep(100);
            sleeptime += 100;
            if (sleeptime == 1000) {
                final int migrateDowntime = libvirtComputingResource.getMigrateDowntime();
                if (migrateDowntime > 0) {
                    try {
                        final int setDowntime = dm.migrateSetMaxDowntime(migrateDowntime);
                        if (setDowntime == 0) {
                            s_logger.debug("Set max downtime for migration of " + vmName + " to " + String.valueOf(migrateDowntime) + "ms");
                        }
                    } catch (final LibvirtException e) {
                        s_logger.debug("Failed to set max downtime for migration, perhaps migration completed? Error: " + e.getMessage());
                    }
                }
            }
            if (sleeptime % 1000 == 0) {
                s_logger.info("Waiting for migration of " + vmName + " to complete, waited " + sleeptime + "ms");
            }
            // pause vm if we meet the vm.migrate.pauseafter threshold and not already paused
            final int migratePauseAfter = libvirtComputingResource.getMigratePauseAfter();
            if (migratePauseAfter > 0 && sleeptime > migratePauseAfter) {
                DomainState state = null;
                try {
                    state = dm.getInfo().state;
                } catch (final LibvirtException e) {
                    s_logger.info("Couldn't get VM domain state after " + sleeptime + "ms: " + e.getMessage());
                }
                if (state != null && state == DomainState.VIR_DOMAIN_RUNNING) {
                    try {
                        s_logger.info("Pausing VM " + vmName + " due to property vm.migrate.pauseafter setting to " + migratePauseAfter + "ms to complete migration");
                        dm.suspend();
                    } catch (final LibvirtException e) {
                        // pause could be racy if it attempts to pause right when vm is finished, simply warn
                        s_logger.info("Failed to pause vm " + vmName + " : " + e.getMessage());
                    }
                }
            }
        }
        s_logger.info("Migration thread for " + vmName + " is done");
        destDomain = migrateThread.get(10, TimeUnit.SECONDS);
        if (destDomain != null) {
            for (final LibvirtDiskDef disk : disks) {
                libvirtComputingResource.cleanupDisk(disk);
            }
        }
    } catch (final LibvirtException e) {
        s_logger.debug("Can't migrate domain: " + e.getMessage());
        result = e.getMessage();
    } catch (final InterruptedException e) {
        s_logger.debug("Interrupted while migrating domain: " + e.getMessage());
        result = e.getMessage();
    } catch (final ExecutionException e) {
        s_logger.debug("Failed to execute while migrating domain: " + e.getMessage());
        result = e.getMessage();
    } catch (final TimeoutException e) {
        s_logger.debug("Timed out while migrating domain: " + e.getMessage());
        result = e.getMessage();
    } finally {
        try {
            if (dm != null && result != null) {
                // restore vm snapshots in case of failed migration
                if (vmsnapshots != null) {
                    libvirtComputingResource.restoreVMSnapshotMetadata(dm, vmName, vmsnapshots);
                }
            }
            if (dm != null) {
                if (dm.isPersistent() == 1) {
                    dm.undefine();
                }
                dm.free();
            }
            if (dconn != null) {
                dconn.close();
            }
            if (destDomain != null) {
                destDomain.free();
            }
        } catch (final LibvirtException e) {
            s_logger.trace("Ignoring libvirt error.", e);
        }
    }
    if (result == null) {
        for (final LibvirtVmDef.InterfaceDef iface : ifaces) {
            // We don't know which "traffic type" is associated with
            // each interface at this point, so inform all vif drivers
            final List<VifDriver> allVifDrivers = libvirtComputingResource.getAllVifDrivers();
            for (final VifDriver vifDriver : allVifDrivers) {
                vifDriver.unplug(iface);
            }
        }
    }
    return new MigrateAnswer(command, result == null, result, null);
}
Also used : LibvirtException(org.libvirt.LibvirtException) MigrateAnswer(com.cloud.legacymodel.communication.answer.MigrateAnswer) LibvirtDiskDef(com.cloud.agent.resource.kvm.xml.LibvirtDiskDef) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) LibvirtVmDef(com.cloud.agent.resource.kvm.xml.LibvirtVmDef) Ternary(com.cloud.legacymodel.utils.Ternary) Connect(org.libvirt.Connect) VifDriver(com.cloud.agent.resource.kvm.vif.VifDriver) DomainState(org.libvirt.DomainInfo.DomainState) ExecutorService(java.util.concurrent.ExecutorService) Domain(org.libvirt.Domain) MigrateKvmAsync(com.cloud.agent.resource.kvm.async.MigrateKvmAsync)

Aggregations

VifDriver (com.cloud.agent.resource.kvm.vif.VifDriver)13 LibvirtException (org.libvirt.LibvirtException)12 Connect (org.libvirt.Connect)11 NicTO (com.cloud.legacymodel.to.NicTO)10 LibvirtRequestWrapper (com.cloud.agent.resource.kvm.wrapper.LibvirtRequestWrapper)8 LibvirtUtilitiesHelper (com.cloud.agent.resource.kvm.wrapper.LibvirtUtilitiesHelper)8 Answer (com.cloud.legacymodel.communication.answer.Answer)8 AttachAnswer (com.cloud.legacymodel.communication.answer.AttachAnswer)8 CheckRouterAnswer (com.cloud.legacymodel.communication.answer.CheckRouterAnswer)8 Test (org.junit.Test)8 Domain (org.libvirt.Domain)8 KvmStoragePoolManager (com.cloud.agent.resource.kvm.storage.KvmStoragePoolManager)4 LibvirtVmDef (com.cloud.agent.resource.kvm.xml.LibvirtVmDef)4 InterfaceDef (com.cloud.agent.resource.kvm.xml.LibvirtVmDef.InterfaceDef)4 PrepareForMigrationCommand (com.cloud.legacymodel.communication.command.PrepareForMigrationCommand)4 UnPlugNicCommand (com.cloud.legacymodel.communication.command.UnPlugNicCommand)4 VirtualMachineTO (com.cloud.legacymodel.to.VirtualMachineTO)4 ArrayList (java.util.ArrayList)4 InternalErrorException (com.cloud.legacymodel.exceptions.InternalErrorException)3 DiskTO (com.cloud.legacymodel.to.DiskTO)3