WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Deprecate XendDomainInfo.state - now use

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Deprecate XendDomainInfo.state - now use _stateGet() to get the live
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 20 Apr 2007 14:50:13 -0700
Delivery-date: Fri, 20 Apr 2007 14:49:15 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Tom Wilkie <tom.wilkie@xxxxxxxxx>
# Date 1177088188 -3600
# Node ID 55135bf6eb4459fb130e9d27f7ccbeb89b86637b
# Parent  53b1cfcf129fd89139723512c3560dac22961aff
Deprecate XendDomainInfo.state - now use _stateGet() to get the live
state of a domain.  Should still call _stateSet() to notify others
when you expect the state has changed.

Also some changes to locking in save/suspend, restore/resume and migrate

Passes xm-test against XenAPI...

signed-off-by: Tom Wilkie <tom.wilkie@xxxxxxxxx>
---
 tools/python/xen/xend/XendCheckpoint.py |   24 +++++++
 tools/python/xen/xend/XendConfig.py     |    2 
 tools/python/xen/xend/XendDomain.py     |   29 ++++-----
 tools/python/xen/xend/XendDomainInfo.py |   97 +++++++++++++++++++++++---------
 4 files changed, 108 insertions(+), 44 deletions(-)

diff -r 53b1cfcf129f -r 55135bf6eb44 tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py   Fri Apr 20 17:51:10 2007 +0100
+++ b/tools/python/xen/xend/XendCheckpoint.py   Fri Apr 20 17:56:28 2007 +0100
@@ -253,8 +253,28 @@ def restore(xd, fd, dominfo = None, paus
         os.read(fd, 1)           # Wait for source to close connection
         
         dominfo.completeRestore(handler.store_mfn, handler.console_mfn)
-        
-        dominfo.waitForDevices() # Wait for backends to set up
+
+        #
+        # We shouldn't hold the domains_lock over a waitForDevices
+        # As this function sometime gets called holding this lock,
+        # we must release it and re-acquire it appropriately
+        #
+        from xen.xend import XendDomain
+
+        lock = True;
+        try:
+            XendDomain.instance().domains_lock.release()
+        except:
+            lock = False;
+
+        try:
+            dominfo.waitForDevices() # Wait for backends to set up
+        except Exception, exn:
+            log.exception(exn)
+
+        if lock:
+            XendDomain.instance().domains_lock.acquire()
+
         if not paused:
             dominfo.unpause()
 
diff -r 53b1cfcf129f -r 55135bf6eb44 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Fri Apr 20 17:51:10 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Fri Apr 20 17:56:28 2007 +0100
@@ -870,7 +870,7 @@ class XendConfig(dict):
                 sxpr.append([legacy, self[legacy]])
 
         sxpr.append(['image', self.image_sxpr()])
-        sxpr.append(['status', domain.state])
+        sxpr.append(['status', domain._stateGet()])
 
         if domain.getDomid() is not None:
             sxpr.append(['state', self._get_old_state_string()])
diff -r 53b1cfcf129f -r 55135bf6eb44 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py       Fri Apr 20 17:51:10 2007 +0100
+++ b/tools/python/xen/xend/XendDomain.py       Fri Apr 20 17:56:28 2007 +0100
@@ -45,6 +45,7 @@ from xen.xend.XendConstants import DOM_S
 from xen.xend.XendConstants import DOM_STATE_SHUTDOWN, DOM_STATE_UNKNOWN
 from xen.xend.XendConstants import TRIGGER_TYPE
 from xen.xend.XendDevices import XendDevices
+from xen.xend.XendAPIConstants import *
 
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.xenstore.xswatch import xswatch
@@ -457,7 +458,7 @@ class XendDomain:
             if domid == None:
                 domid = info.getDomid()
 
-            if info.state != DOM_STATE_HALTED:
+            if info._stateGet() != DOM_STATE_HALTED:
                 info.cleanupDomain()
             
             if domid in self.domains:
@@ -577,7 +578,7 @@ class XendDomain:
         self.domains_lock.acquire()
         try:
             for dom_uuid, dom in self.managed_domains.items():
-                if dom and dom.state == DOM_STATE_HALTED:
+                if dom and dom._stateGet() == DOM_STATE_HALTED:
                     on_xend_start = dom.info.get('on_xend_start', 'ignore')
                     auto_power_on = dom.info.get('auto_power_on', False)
                     should_start = (on_xend_start == 'start') or auto_power_on
@@ -602,7 +603,7 @@ class XendDomain:
                 if dom.getName() == DOM0_NAME:
                     continue
                 
-                if dom.state == DOM_STATE_RUNNING:
+                if dom._stateGet() == DOM_STATE_RUNNING:
                     shutdownAction = dom.info.get('on_xend_stop', 'ignore')
                     if shutdownAction == 'shutdown':
                         log.debug('Shutting down domain: %s' % dom.getName())
@@ -780,7 +781,7 @@ class XendDomain:
                 return active_domains + inactive_domains
             else:
                 return filter(lambda x:
-                                  POWER_STATE_NAMES[x.state].lower() == state,
+                                  POWER_STATE_NAMES[x._stateGet()].lower() == 
state,
                               active_domains + inactive_domains)
         finally:
             self.domains_lock.release()
@@ -825,10 +826,10 @@ class XendDomain:
             if dominfo.getDomid() == DOM0_ID:
                 raise XendError("Cannot save privileged domain %s" % domname)
 
-            if dominfo.state != DOM_STATE_RUNNING:
+            if dominfo._stateGet() != DOM_STATE_RUNNING:
                 raise VMBadState("Domain is not running",
                                  POWER_STATE_NAMES[DOM_STATE_RUNNING],
-                                 POWER_STATE_NAMES[dominfo.state])
+                                 POWER_STATE_NAMES[dominfo._stateGet()])
 
             dom_uuid = dominfo.get_uuid()
 
@@ -869,8 +870,8 @@ class XendDomain:
                 if dominfo.getDomid() == DOM0_ID:
                     raise XendError("Cannot save privileged domain %s" % 
domname)
 
-                if dominfo.state != DOM_STATE_HALTED:
-                    raise XendError("Cannot resume domain that is not halted.")
+                if dominfo._stateGet() != XEN_API_VM_POWER_STATE_SUSPENDED:
+                    raise XendError("Cannot resume domain that is not 
suspended.")
 
                 dom_uuid = dominfo.get_uuid()
                 chkpath = self._managed_check_point_path(dom_uuid)
@@ -879,7 +880,7 @@ class XendDomain:
 
                 # Restore that replaces the existing XendDomainInfo
                 try:
-                    log.debug('Current DomainInfo state: %d' % dominfo.state)
+                    log.debug('Current DomainInfo state: %d' % 
dominfo._stateGet())
                     oflags = os.O_RDONLY
                     if hasattr(os, "O_LARGEFILE"):
                         oflags |= os.O_LARGEFILE
@@ -974,10 +975,10 @@ class XendDomain:
             if not dominfo:
                 raise XendInvalidDomain(str(domid))
 
-            if dominfo.state != DOM_STATE_HALTED:
+            if dominfo._stateGet() != DOM_STATE_HALTED:
                 raise VMBadState("Domain is already running",
                                  POWER_STATE_NAMES[DOM_STATE_HALTED],
-                                 POWER_STATE_NAMES[dominfo.state])
+                                 POWER_STATE_NAMES[dominfo._stateGet()])
             
             dominfo.start(is_managed = True)
         finally:
@@ -1003,10 +1004,10 @@ class XendDomain:
                 if not dominfo:
                     raise XendInvalidDomain(str(domid))
 
-                if dominfo.state != DOM_STATE_HALTED:
-                    raise VMBadState("Domain is still running",
+                if dominfo._stateGet() != XEN_API_VM_POWER_STATE_HALTED:
+                    raise VMBadState("Domain is not halted.",
                                      POWER_STATE_NAMES[DOM_STATE_HALTED],
-                                     POWER_STATE_NAMES[dominfo.state])
+                                     POWER_STATE_NAMES[dominfo._stateGet()])
                 
                 self._domain_delete_by_info(dominfo)
             except Exception, ex:
diff -r 53b1cfcf129f -r 55135bf6eb44 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Fri Apr 20 17:51:10 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Fri Apr 20 17:56:28 2007 +0100
@@ -30,6 +30,7 @@ import re
 import re
 import copy
 import os
+import traceback
 from types import StringTypes
 
 import xen.lowlevel.xc
@@ -309,8 +310,8 @@ class XendDomainInfo:
     @type shutdownWatch: xen.xend.xenstore.xswatch
     @ivar shutdownStartTime: UNIX Time when domain started shutting down.
     @type shutdownStartTime: float or None
-    @ivar state: Domain state
-    @type state: enum(DOM_STATE_HALTED, DOM_STATE_RUNNING, ...)
+#    @ivar state: Domain state
+#    @type state: enum(DOM_STATE_HALTED, DOM_STATE_RUNNING, ...)
     @ivar state_updated: lock for self.state
     @type state_updated: threading.Condition
     @ivar refresh_shutdown_lock: lock for polling shutdown state
@@ -361,9 +362,9 @@ class XendDomainInfo:
         self.shutdownStartTime = None
         self._resume = resume
 
-        self.state = DOM_STATE_HALTED
         self.state_updated = threading.Condition()
         self.refresh_shutdown_lock = threading.Condition()
+        self._stateSet(DOM_STATE_HALTED)
 
         self._deviceControllers = {}
 
@@ -389,7 +390,7 @@ class XendDomainInfo:
         """
         from xen.xend import XendDomain
 
-        if self.state == DOM_STATE_HALTED:
+        if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED, 
XEN_API_VM_POWER_STATE_SUSPENDED):
             try:
                 XendTask.log_progress(0, 30, self._constructDomain)
                 XendTask.log_progress(31, 60, self._initDomain)
@@ -420,7 +421,8 @@ class XendDomainInfo:
 
     def resume(self):
         """Resumes a domain that has come back from suspension."""
-        if self.state in (DOM_STATE_HALTED, DOM_STATE_SUSPENDED):
+        state = self._stateGet()
+        if state in (DOM_STATE_SUSPENDED, DOM_STATE_HALTED):
             try:
                 self._constructDomain()
                 self._storeVmDetails()
@@ -433,12 +435,13 @@ class XendDomainInfo:
                 self.destroy()
                 raise
         else:
-            raise XendError('VM already running')
+            raise XendError('VM is not susupened; it is %s'
+                            % XEN_API_VM_POWER_STATE[state])
 
     def shutdown(self, reason):
         """Shutdown a domain by signalling this via xenstored."""
         log.debug('XendDomainInfo.shutdown(%s)', reason)
-        if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
+        if self._stateGet() in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
             raise XendError('Domain cannot be shutdown')
 
         if self.domid == 0:
@@ -558,8 +561,7 @@ class XendDomainInfo:
         return self.getDeviceController(deviceClass).destroyDevice(devid, 
force)
 
     def getDeviceSxprs(self, deviceClass):
-        if self.state == DOM_STATE_RUNNING \
-               or self.state == DOM_STATE_PAUSED:
+        if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
             return self.getDeviceController(deviceClass).sxprs()
         else:
             sxprs = []
@@ -1579,11 +1581,10 @@ class XendDomainInfo:
     def waitForShutdown(self):
         self.state_updated.acquire()
         try:
-            while self.state in (DOM_STATE_RUNNING,DOM_STATE_PAUSED):
+            while self._stateGet() in (DOM_STATE_RUNNING,DOM_STATE_PAUSED):
                 self.state_updated.wait()
         finally:
             self.state_updated.release()
-
 
     #
     # TODO: recategorise - called from XendCheckpoint
@@ -1980,17 +1981,59 @@ class XendDomainInfo:
     # Utility functions
     #
 
+    def __getattr__(self, name):
+         if name == "state":
+             log.warn("Somebody tried to read XendDomainInfo.state... should 
us _stateGet()!!!")
+             log.warn("".join(traceback.format_stack()))
+             return self._stateGet()
+         else:
+             raise AttributeError()
+
+    def __setattr__(self, name, value):
+        if name == "state":
+            log.warn("Somebody tried to set XendDomainInfo.state... should us 
_stateGet()!!!")
+            log.warn("".join(traceback.format_stack()))
+            self._stateSet(value)
+        else:
+            self.__dict__[name] = value
+
     def _stateSet(self, state):
         self.state_updated.acquire()
         try:
-            if self.state != state:
-                self.state = state
+            # TODO Not sure this is correct...
+            # _stateGet is live now. Why not fire event
+            # even when it hasn't changed?
+            if self._stateGet() != state:
                 self.state_updated.notifyAll()
                 import XendAPI
                 XendAPI.event_dispatch('mod', 'VM', self.info['uuid'],
                                        'power_state')
         finally:
             self.state_updated.release()
+
+    def _stateGet(self):
+        # Lets try and reconsitute the state from xc
+        # first lets try and get the domain info
+        # from xc - this will tell us if the domain
+        # exists
+        info = dom_get(self.getDomid())
+        if info is None or info['shutdown']:
+            # We are either HALTED or SUSPENDED
+            # check saved image exists
+            from xen.xend import XendDomain
+            managed_config_path = \
+                XendDomain.instance()._managed_check_point_path( \
+                    self.get_uuid())
+            if os.path.exists(managed_config_path):
+                return XEN_API_VM_POWER_STATE_SUSPENDED
+            else:
+                return XEN_API_VM_POWER_STATE_HALTED
+        else:
+            # We are either RUNNING or PAUSED
+            if info['paused']:
+                return XEN_API_VM_POWER_STATE_PAUSED
+            else:
+                return XEN_API_VM_POWER_STATE_RUNNING
 
     def _infoIsSet(self, name):
         return name in self.info and self.info[name] is not None
@@ -2107,7 +2150,7 @@ class XendDomainInfo:
         retval = xc.sched_credit_domain_get(self.getDomid())
         return retval
     def get_power_state(self):
-        return XEN_API_VM_POWER_STATE[self.state]
+        return XEN_API_VM_POWER_STATE[self._stateGet()]
     def get_platform(self):
         return self.info.get('platform', {})    
     def get_pci_bus(self):
@@ -2156,7 +2199,7 @@ class XendDomainInfo:
         # shortcut if the domain isn't started because
         # the devcontrollers will have no better information
         # than XendConfig.
-        if self.state in (XEN_API_VM_POWER_STATE_HALTED,):
+        if self._stateGet() in (XEN_API_VM_POWER_STATE_HALTED,):
             if dev_config:
                 return copy.deepcopy(dev_config)
             return None
@@ -2215,7 +2258,7 @@ class XendDomainInfo:
 
             config['MTU'] = 1500 # TODO
             
-            if self.state not in (XEN_API_VM_POWER_STATE_HALTED,):
+            if self._stateGet() not in (XEN_API_VM_POWER_STATE_HALTED,):
                 xennode = XendNode.instance()
                 rx_bps, tx_bps = xennode.get_vif_util(self.domid, devid)
                 config['io_read_kbs'] = rx_bps/1024
@@ -2226,7 +2269,7 @@ class XendDomainInfo:
 
         if dev_class == 'vbd':
 
-            if self.state not in (XEN_API_VM_POWER_STATE_HALTED,):
+            if self._stateGet() not in (XEN_API_VM_POWER_STATE_HALTED,):
                 controller = self.getDeviceController(dev_class)
                 devid, _1, _2 = controller.getDeviceDetails(config)
                 xennode = XendNode.instance()
@@ -2312,8 +2355,8 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
 
-        if self.state == XEN_API_VM_POWER_STATE_RUNNING or \
-               self.state == XEN_API_VM_POWER_STATE_PAUSED:
+        if self._stateGet() in (XEN_API_VM_POWER_STATE_RUNNING,
+                                XEN_API_VM_POWER_STATE_PAUSED):
             _, config = self.info['devices'][dev_uuid]
             
             if vdi_image_path.startswith('tap'):
@@ -2347,7 +2390,7 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
 
-        if self.state == XEN_API_VM_POWER_STATE_RUNNING:
+        if self._stateGet() == XEN_API_VM_POWER_STATE_RUNNING:
             _, config = self.info['devices'][dev_uuid]
             config['devid'] = 
self.getDeviceController('tap').createDevice(config)
 
@@ -2364,8 +2407,8 @@ class XendDomainInfo:
         if not dev_uuid:
             raise XendError('Failed to create device')
         
-        if self.state == XEN_API_VM_POWER_STATE_RUNNING \
-               or self.state == XEN_API_VM_POWER_STATE_PAUSED:
+        if self._stateGet() in (XEN_API_VM_POWER_STATE_RUNNING,
+                                XEN_API_VM_POWER_STATE_PAUSED):
 
             _, config = self.info['devices'][dev_uuid]
             dev_control = self.getDeviceController('vif')
@@ -2390,7 +2433,7 @@ class XendDomainInfo:
         @rtype: string
         """
 
-        if self.state not in (DOM_STATE_HALTED,):
+        if self._stateGet() not in (DOM_STATE_HALTED,):
             raise VmError("Can only add vTPM to a halted domain.")
         if self.get_vtpms() != []:
             raise VmError('Domain already has a vTPM.')
@@ -2406,7 +2449,7 @@ class XendDomainInfo:
         @return: uuid of device
         @rtype: string
         """
-        if self.state not in (DOM_STATE_HALTED,):
+        if self._stateGet() not in (DOM_STATE_HALTED,):
             raise VmError("Can only add console to a halted domain.")
 
         dev_uuid = self.info.device_add('console', cfg_xenapi = xenapi_console)
@@ -2420,8 +2463,8 @@ class XendDomainInfo:
             raise XendError('Device does not exist')
 
         try:
-            if self.state == XEN_API_VM_POWER_STATE_RUNNING \
-                   or self.state == XEN_API_VM_POWER_STATE_PAUSED:
+            if self._stateGet() in (XEN_API_VM_POWER_STATE_RUNNING,
+                                    XEN_API_VM_POWER_STATE_PAUSED):
                 _, config = self.info['devices'][dev_uuid]
                 devid = config.get('devid')
                 if devid != None:
@@ -2448,7 +2491,7 @@ class XendDomainInfo:
     def __str__(self):
         return '<domain id=%s name=%s memory=%s state=%s>' % \
                (str(self.domid), self.info['name_label'],
-                str(self.info['memory_dynamic_max']), DOM_STATES[self.state])
+                str(self.info['memory_dynamic_max']), 
DOM_STATES[self._stateGet()])
 
     __repr__ = __str__
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Deprecate XendDomainInfo.state - now use _stateGet() to get the live, Xen patchbot-unstable <=