[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xend: Make device detach wait for detach to complete.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1181553671 -3600
# Node ID 31ee1768e911336c227d13fd1519961d07cdc562
# Parent  6f06bd06ef473726b4132e6fe95309fce6963fd5
xend: Make device detach wait for detach to complete.

*-detach will wait till device is detached or time'ed out.
XendConfig will be updated, if detached.

Signed-off-by: Max Zhen <max.zhen@xxxxxxx>
---
 tools/python/xen/xend/XendConfig.py           |   15 ++++++++
 tools/python/xen/xend/XendDomainInfo.py       |   19 +++++++++-
 tools/python/xen/xend/server/DevController.py |   46 ++++++++++++++++++++++++--
 3 files changed, 75 insertions(+), 5 deletions(-)

diff -r 6f06bd06ef47 -r 31ee1768e911 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py       Mon Jun 11 10:16:54 2007 +0100
+++ b/tools/python/xen/xend/XendConfig.py       Mon Jun 11 10:21:11 2007 +0100
@@ -1268,6 +1268,21 @@ class XendConfig(dict):
 
         return False
 
+    def device_remove(self, dev_uuid):
+        """Remove an existing device referred by dev_uuid.
+        """
+
+        if dev_uuid in self['devices']:
+            dev_config = self['devices'].get(dev_uuid)
+            dev_type = dev_config[0]
+
+            del self['devices'][dev_uuid]
+            # Remove dev references for certain device types (see device_add)
+            if dev_type in ('vif', 'vbd', 'vtpm'):
+                param = '%s_refs' % dev_type
+                if param in self:
+                    if dev_uuid in self[param]:
+                        self[param].remove(dev_uuid)
 
     def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
         """Get Device SXPR by either giving the device UUID or (type, config).
diff -r 6f06bd06ef47 -r 31ee1768e911 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Mon Jun 11 10:16:54 2007 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Mon Jun 11 10:21:11 2007 +0100
@@ -557,7 +557,23 @@ class XendDomainInfo:
                 return None
 
         log.debug("dev = %s", dev)
-        return self.getDeviceController(deviceClass).destroyDevice(dev, force)
+
+        dev_control = self.getDeviceController(deviceClass)
+        dev_uuid = dev_control.readBackend(dev, 'uuid')
+
+        ret = None
+
+        try:
+            ret = dev_control.destroyDevice(dev, force)
+        except EnvironmentError:
+            # We failed to detach the device
+            raise VmError("Failed to detach device %d" % dev)
+
+        # update XendConfig
+        if dev_uuid:
+            self.info.device_remove(dev_uuid)
+
+        return ret
 
     def getDeviceSxprs(self, deviceClass):
         if self._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED):
@@ -570,7 +586,6 @@ class XendDomainInfo:
                     sxprs.append([dev_num, dev_info])
                     dev_num += 1
             return sxprs
-
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.
diff -r 6f06bd06ef47 -r 31ee1768e911 
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py     Mon Jun 11 10:16:54 
2007 +0100
+++ b/tools/python/xen/xend/server/DevController.py     Mon Jun 11 10:21:11 
2007 +0100
@@ -29,6 +29,7 @@ import os
 import os
 
 DEVICE_CREATE_TIMEOUT = 100
+DEVICE_DESTROY_TIMEOUT = 10
 HOTPLUG_STATUS_NODE = "hotplug-status"
 HOTPLUG_ERROR_NODE  = "hotplug-error"
 HOTPLUG_STATUS_ERROR = "error"
@@ -211,17 +212,34 @@ class DevController:
 
         devid = int(devid)
 
+        frontpath = self.frontendPath(devid)
+       if frontpath:
+            backpath = xstransact.Read(frontpath, "backend")
+
         # Modify online status /before/ updating state (latter is watched by
         # drivers, so this ordering avoids a race).
         self.writeBackend(devid, 'online', "0")
         self.writeBackend(devid, 'state', str(xenbusState['Closing']))
 
         if force:
-            frontpath = self.frontendPath(devid)
-            backpath = xstransact.Read(frontpath, "backend")
             if backpath:
                 xstransact.Remove(backpath)
-            xstransact.Remove(frontpath)
+           if frontpath:
+                xstransact.Remove(frontpath)
+           return
+
+       # Wait till both frontpath and backpath are removed from
+       # xenstore, or timed out
+       if frontpath:
+           status = self.waitUntilDestroyed(frontpath)
+           if status == Timeout:
+               # Exception will be caught by destroyDevice in XendDomainInfo.py
+               raise EnvironmentError
+       if backpath:
+           status = self.waitUntilDestroyed(backpath)
+           if status == Timeout:
+               # Exception will be caught by destroyDevice in XendDomainInfo.py
+               raise EnvironmentError
 
         self.vm._removeVm("device/%s/%d" % (self.deviceClass, devid))
 
@@ -508,6 +526,16 @@ class DevController:
             return (Missing, None)
 
 
+    def waitUntilDestroyed(self, path):
+       ev = Event()
+       result = { 'path': path, 'status': Timeout }
+
+       xswatch(path, destroyCallback, ev, result)
+
+       ev.wait(DEVICE_DESTROY_TIMEOUT)
+       return result['status']
+
+
     def backendPath(self, backdom, devid):
         """Construct backend path given the backend domain and device id.
 
@@ -537,6 +565,18 @@ class DevController:
                                       self.deviceClass)
 
 
+def destroyCallback(devPath, ev, result):
+    log.debug("destroyCallback %s.", devPath)
+
+    list = xstransact.List(result['path'])
+    if list:
+        return 1
+
+    result['status'] = Missing
+    ev.set()
+    log.debug("destroyCallback %s is destroyed", result['path'])
+    return 0
+
 def hotplugStatusCallback(statusPath, ev, result):
     log.debug("hotplugStatusCallback %s.", statusPath)
 

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.