Commit 71ab2daf authored by Anael Beutot's avatar Anael Beutot
Browse files

Fix weird libvirt behaviour.

sending events on removed domains or sending removed event too late.
parent 90a97263
Loading
Loading
Loading
Loading
+33 −15
Original line number Diff line number Diff line
@@ -672,30 +672,48 @@ class Hypervisor(object):
            logger.info('Created domain %s', vm.name)
            self.domains[vm.name] = vm
            self.handler.tag_db.add_sub_object(vm.name, vm.tags.itervalues())
            self.update_domain_count()
        elif event == 'Removed':
            try:
                vm = self.domains.pop(dom.name())
            except KeyError:
                # domain already removed, see hypervisor/domains/vm_tags.py
                # sometimes libvirt send us the remove event too late
                # we still update storage and tag attributes
                pass
            else:
                self.handler.tag_db.remove_sub_object(vm.name)
                # update Storage pools in case VM had volumes that were deleted
            self.vm_unregister(dom.name())
            logger.info('Removed domain %s', vm.name)
            self.storage.update()
        elif event in ('Started', 'Suspended', 'Resumed', 'Stopped', 'Saved',
                       'Restored'):
            vm = self.domains.get(dom.name())
            # sometimes libvirt sent a start event before a created event so be
            # careful
            if vm is not None:
                try:
                    state = DOMAIN_STATES[dom.info()[0]]
                except libvirt.libvirtError as exc:
                    # checks that domain was not previously removed
                    # seems to happen only in libvirt 0.8.8
                    if 'Domain not found' in str(exc):
                        self.vm_unregister(dom.name())
                    else:
                        raise
                else:
                    logger.info('Domain change state from %s to %s', vm.state,
                                 state)
                    vm.state = state
                    self.update_domain_count()

    def vm_unregister(self, name):
        """Unregister a VM from the cc-server and remove it from the index."""
        try:
            vm = self.domains.pop(name)
        except KeyError:
            # domain already removed, see hypervisor/domains/vm_tags.py
            # sometimes libvirt send us the remove event too late
            # we still update storage and tag attributes
            pass
        else:
            self.handler.tag_db.remove_sub_object(vm.name)
            # update Storage pools in case VM had volumes that were deleted
            self.storage.update()
            self.update_domain_count()

    def update_domain_count(self):
        """Update domain state count tags."""
        # update domain state counts
        for tag in ('nvm', 'vmpaused', 'vmstarted', 'vmstopped'):
            self.handler.tag_db['__main__'][tag].update_value()
+1 −2
Original line number Diff line number Diff line
@@ -27,8 +27,7 @@ def _vir_tag(func):
            if 'Domain not found' in str(exc):
                # sometimes, libvirt tells us too late when a domain is removed
                # we just ignore the error and remove the domain
                dom.hypervisor.domains.pop(dom.name)
                dom.hypervisor.handler.tag_db.remove_sub_object(dom.name)
                dom.hypervisor.vm_unregister(dom.name)
                return
            logger.exception('Unexpected libvirt error')
            dom.hypervisor.handler.virt_connect_restart()