[NEW PATCH] Revert "BZ#701398 Set monitorResponse using controlInfo" (via gerrit-bot)

Dan Kenigsberg danken at redhat.com
Sun Jul 10 19:16:21 UTC 2011


New patch submitted by Dan Kenigsberg (danken at redhat.com)

You can review this change at: http://gerrit.usersys.redhat.com/681

commit 18e6933884d7411a359d01fe58289ae528597df0
Author: Dan Kenigsberg <danken at redhat.com>
Date:   Sun Jul 10 19:13:01 2011 +0300

    Revert "BZ#701398 Set monitorResponse using controlInfo"
    
    This reverts commit e1a615c9ad91fe5f7fe147cded028954e80ccf08.
    
    Libvirt-0.9.3 is not yet ready for our consumption; Furthermore, the
    reverted commit does not solve the case of blocked libvirtd.
    
    Change-Id: I1e6286db657b2532835f0d9cc82d6379b2b8aeee

diff --git a/vdsm.spec.in b/vdsm.spec.in
index 8f01acc..f805602 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -28,7 +28,7 @@ Requires: psmisc >= 22.6-15.el6_0.1
 Requires: fence-agents
 Requires: bridge-utils
 Requires: sos
-Requires: libvirt >= 0.9.3
+Requires: libvirt >= 0.8.7-5
 Requires: libvirt-python
 Requires: dosfstools
 Requires: policycoreutils-python
diff --git a/vdsm/libvirtvm.py b/vdsm/libvirtvm.py
index 0516c3b..40567a5 100644
--- a/vdsm/libvirtvm.py
+++ b/vdsm/libvirtvm.py
@@ -283,6 +283,35 @@ class MigrationSourceThread(vm.MigrationSourceThread):
                 if MigrationMonitorThread._MIGRATION_MONITOR_INTERVAL:
                     monitorThread.stop()
 
+class TimeoutError(libvirt.libvirtError): pass
+
+class NotifyingVirDomain:
+    # virDomain wrapper that notifies vm when a method raises an exception with
+    # get_error_code() = VIR_ERR_OPERATION_TIMEOUT
+
+    def __init__(self, dom, tocb):
+        self._dom = dom
+        self._cb = tocb
+
+    def __getattr__(self, name):
+        attr = getattr(self._dom, name)
+        if not callable(attr):
+            return attr
+        def f(*args, **kwargs):
+            try:
+                ret = attr(*args, **kwargs)
+                self._cb(False)
+                return ret
+            except libvirt.libvirtError, e:
+                if e.get_error_code() == libvirt.VIR_ERR_OPERATION_TIMEOUT:
+                    self._cb(True)
+                    toe = TimeoutError(e.get_error_message())
+                    toe.err = e.err
+                    raise toe
+                raise
+        return f
+
+
 class _DomXML:
     def __init__(self, conf, log):
         """
@@ -888,7 +917,9 @@ class LibvirtVm(vm.Vm):
             domxml = hooks.before_vm_start(self._buildCmdLine(), self.conf)
             self.log.debug(domxml)
         if 'recover' in self.conf:
-            self._dom = self._connection.lookupByUUIDString(self.id)
+            self._dom = NotifyingVirDomain(
+                            self._connection.lookupByUUIDString(self.id),
+                            self._timeoutExperienced)
         elif 'restoreState' in self.conf:
             hooks.before_vm_dehibernate(self.conf.pop('_srcDomXML'), self.conf)
 
@@ -898,14 +929,18 @@ class LibvirtVm(vm.Vm):
             finally:
                 self.cif._teardownVolumePath(self.conf['restoreState'])
 
-            self._dom = self._connection.lookupByUUIDString(self.id)
+            self._dom = NotifyingVirDomain(
+                            self._connection.lookupByUUIDString(self.id),
+                            self._timeoutExperienced)
         else:
             flags = libvirt.VIR_DOMAIN_NONE
             if 'launchPaused' in self.conf:
                 flags |= libvirt.VIR_DOMAIN_START_PAUSED
                 self.conf['pauseCode'] = 'NOERR'
                 del self.conf['launchPaused']
-            self._dom = self._connection.createXML(domxml, flags)
+            self._dom = NotifyingVirDomain(
+                            self._connection.createXML(domxml, flags),
+                            self._timeoutExperienced)
             if self._dom.UUIDString() != self.id:
                 raise Exception('libvirt bug 603494')
             hooks.after_vm_start(self._dom.XMLDesc(0), self.conf)
@@ -933,25 +968,11 @@ class LibvirtVm(vm.Vm):
     def _monitorDependentInit(self, timeout=None):
         self.log.warning('unsupported by libvirt vm')
 
-    def _getMonitorResponse(self):
-        if not self._dom:
-            return 0
-
-        state, details, stateTime = self._dom.controlInfo(0)
-        stateTime /= 1000.0
-
-        if (state == libvirt.VIR_DOMAIN_CONTROL_OCCUPIED and
-            stateTime > config.getint('vars', 'vm_command_timeout')):
-            return -1
-
-        return 0
-
-    def _setMonitorResponse(self, value):
-        if value != 0:
-            self.log.debug("failed to set monitorResponse to %s",
-                           value, exc_info=True)
-
-    _monitorResponse = property(_getMonitorResponse, _setMonitorResponse)
+    def _timeoutExperienced(self, timeout):
+        if timeout:
+            self._monitorResponse = -1
+        else:
+            self._monitorResponse = 0
 
     def _waitForIncomingMigrationFinish(self):
         if 'restoreState' in self.conf:
@@ -965,7 +986,9 @@ class LibvirtVm(vm.Vm):
             try:
                 # Would fail if migration isn't successful,
                 # or restart vdsm if connection to libvirt was lost
-                self._dom = self._connection.lookupByUUIDString(self.id)
+                self._dom = NotifyingVirDomain(
+                                self._connection.lookupByUUIDString(self.id),
+                                self._timeoutExperienced)
             except Exception, e:
                 # Improve description of exception
                 if not self._incomingMigrationFinished.isSet():
diff --git a/vdsm/utils.py b/vdsm/utils.py
index bd62925..89f786f 100644
--- a/vdsm/utils.py
+++ b/vdsm/utils.py
@@ -407,16 +407,20 @@ class StatsThread(threading.Thread):
         pass
 
     def run(self):
+        import libvirtvm
         try:
             # wait a bit before starting to sample
             time.sleep(self.SAMPLE_INTERVAL_SEC)
             while not self._stopEvent.isSet():
                 if not self._paused:
-                    sample = self.sample()
-                    self._samples.append(sample)
-                    self._lastSampleTime = sample.timestamp
-                    if len(self._samples) > self.AVERAGING_WINDOW:
-                        self._samples.pop(0)
+                    try:
+                        sample = self.sample()
+                        self._samples.append(sample)
+                        self._lastSampleTime = sample.timestamp
+                        if len(self._samples) > self.AVERAGING_WINDOW:
+                            self._samples.pop(0)
+                    except libvirtvm.TimeoutError:
+                        self._log.error(traceback.format_exc())
                 self._stopEvent.wait(self.SAMPLE_INTERVAL_SEC)
         except:
             if not self._stopEvent.isSet():
diff --git a/vdsm/vm.py b/vdsm/vm.py
index 3653d82..ecc8e70 100644
--- a/vdsm/vm.py
+++ b/vdsm/vm.py
@@ -796,6 +796,10 @@ class Vm(object):
         try:
             if self._vmStats:
                 decStats = self._vmStats.get()
+                if (not self._migrationSourceThread.isAlive()
+                    and decStats['statsAge'] > config.getint('vars',
+                                                       'vm_command_timeout')):
+                    stats['monitorResponse'] = '-1'
         except:
             self.log.error("Error fetching vm stats", exc_info=True)
         for var in decStats:




More information about the vdsm-patches mailing list