|
92 | 92 | import org.libvirt.SchedUlongParameter; |
93 | 93 | import org.libvirt.Secret; |
94 | 94 | import org.libvirt.VcpuInfo; |
95 | | -import org.libvirt.event.DomainEvent; |
96 | | -import org.libvirt.event.DomainEventDetail; |
97 | | -import org.libvirt.event.StoppedDetail; |
98 | 95 | import org.w3c.dom.Document; |
99 | 96 | import org.w3c.dom.Element; |
100 | 97 | import org.w3c.dom.Node; |
@@ -468,7 +465,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv |
468 | 465 | protected CPUStat cpuStat = new CPUStat(); |
469 | 466 | protected MemStat memStat = new MemStat(dom0MinMem, dom0OvercommitMem); |
470 | 467 | private final LibvirtUtilitiesHelper libvirtUtilitiesHelper = new LibvirtUtilitiesHelper(); |
471 | | - private AgentStatusUpdater _agentStatusUpdater; |
| 468 | + private LibvirtDomainListener libvirtDomainListener; |
472 | 469 |
|
473 | 470 | protected Boolean enableManuallySettingCpuTopologyOnKvmVm = AgentPropertiesFileHandler.getPropertyValue(AgentProperties.ENABLE_MANUALLY_SETTING_CPU_TOPOLOGY_ON_KVM_VM); |
474 | 471 |
|
@@ -502,8 +499,23 @@ protected long getHypervisorQemuVersion() { |
502 | 499 | } |
503 | 500 |
|
504 | 501 | @Override |
505 | | - public void registerStatusUpdater(AgentStatusUpdater updater) { |
506 | | - _agentStatusUpdater = updater; |
| 502 | + public synchronized void registerStatusUpdater(AgentStatusUpdater updater) { |
| 503 | + if (AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_EVENTS_ENABLED)) { |
| 504 | + try { |
| 505 | + Connect conn = LibvirtConnection.getConnection(); |
| 506 | + if (libvirtDomainListener != null) { |
| 507 | + s_logger.debug("Clearing old domain listener"); |
| 508 | + conn.removeLifecycleListener(libvirtDomainListener); |
| 509 | + } |
| 510 | + libvirtDomainListener = new LibvirtDomainListener(updater); |
| 511 | + conn.addLifecycleListener(libvirtDomainListener); |
| 512 | + s_logger.debug("Set up the libvirt domain event lifecycle listener"); |
| 513 | + } catch (LibvirtException e) { |
| 514 | + s_logger.error("Failed to get libvirt connection for domain event lifecycle", e); |
| 515 | + } |
| 516 | + } else { |
| 517 | + s_logger.debug("Libvirt event listening is disabled, not registering status updater"); |
| 518 | + } |
507 | 519 | } |
508 | 520 |
|
509 | 521 | @Override |
@@ -1878,6 +1890,10 @@ public String startVM(final Connect conn, final String vmName, final String doma |
1878 | 1890 | public boolean stop() { |
1879 | 1891 | try { |
1880 | 1892 | final Connect conn = LibvirtConnection.getConnection(); |
| 1893 | + if (AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_EVENTS_ENABLED) && libvirtDomainListener != null) { |
| 1894 | + s_logger.debug("Clearing old domain listener"); |
| 1895 | + conn.removeLifecycleListener(libvirtDomainListener); |
| 1896 | + } |
1881 | 1897 | conn.close(); |
1882 | 1898 | } catch (final LibvirtException e) { |
1883 | 1899 | s_logger.trace("Ignoring libvirt error.", e); |
@@ -3688,50 +3704,9 @@ private StartupStorageCommand createLocalStoragePool(String localStoragePath, St |
3688 | 3704 | } catch (final CloudRuntimeException e) { |
3689 | 3705 | s_logger.debug("Unable to initialize local storage pool: " + e); |
3690 | 3706 | } |
3691 | | - setupLibvirtEventListener(); |
3692 | 3707 | return sscmd; |
3693 | 3708 | } |
3694 | 3709 |
|
3695 | | - private void setupLibvirtEventListener() { |
3696 | | - try { |
3697 | | - Connect conn = LibvirtConnection.getConnection(); |
3698 | | - conn.addLifecycleListener(this::onDomainLifecycleChange); |
3699 | | - |
3700 | | - s_logger.debug("Set up the libvirt domain event lifecycle listener"); |
3701 | | - } catch (LibvirtException e) { |
3702 | | - s_logger.error("Failed to get libvirt connection for domain event lifecycle", e); |
3703 | | - } |
3704 | | - } |
3705 | | - |
3706 | | - private int onDomainLifecycleChange(Domain domain, DomainEvent domainEvent) { |
3707 | | - try { |
3708 | | - s_logger.debug(String.format("Got event lifecycle change on Domain %s, event %s", domain.getName(), domainEvent)); |
3709 | | - if (domainEvent != null) { |
3710 | | - switch (domainEvent.getType()) { |
3711 | | - case STOPPED: |
3712 | | - /* libvirt-destroyed VMs have detail StoppedDetail.DESTROYED, self shutdown guests are StoppedDetail.SHUTDOWN |
3713 | | - * Checking for this helps us differentiate between events where cloudstack or admin stopped the VM vs guest |
3714 | | - * initiated, and avoid pushing extra updates for actions we are initiating without a need for extra tracking */ |
3715 | | - DomainEventDetail detail = domainEvent.getDetail(); |
3716 | | - if (StoppedDetail.SHUTDOWN.equals(detail) || StoppedDetail.CRASHED.equals(detail) || StoppedDetail.FAILED.equals(detail)) { |
3717 | | - s_logger.info("Triggering out of band status update due to completed self-shutdown or crash of VM"); |
3718 | | - _agentStatusUpdater.triggerUpdate(); |
3719 | | - } else { |
3720 | | - s_logger.debug("Event detail: " + detail); |
3721 | | - } |
3722 | | - break; |
3723 | | - default: |
3724 | | - s_logger.debug(String.format("No handling for event %s", domainEvent)); |
3725 | | - } |
3726 | | - } |
3727 | | - } catch (LibvirtException e) { |
3728 | | - s_logger.error("Libvirt exception while processing lifecycle event", e); |
3729 | | - } catch (Throwable e) { |
3730 | | - s_logger.error("Error during lifecycle", e); |
3731 | | - } |
3732 | | - return 0; |
3733 | | - } |
3734 | | - |
3735 | 3710 | public String diskUuidToSerial(String uuid) { |
3736 | 3711 | String uuidWithoutHyphen = uuid.replace("-",""); |
3737 | 3712 | return uuidWithoutHyphen.substring(0, Math.min(uuidWithoutHyphen.length(), 20)); |
|
0 commit comments