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-devel

[Xen-devel] [PATCH] Make device detach wait for detach to complete

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] Make device detach wait for detach to complete
From: john.levon@xxxxxxx
Date: Fri, 08 Jun 2007 05:22:13 -0700
Delivery-date: Fri, 08 Jun 2007 05:20:36 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User john.levon@xxxxxxx
# Date 1181305288 25200
# Node ID b6e22518c35a85e708a62ac526daeb18d16f28a2
# Parent  286d8ec9ccf4082b8db0a17a8ab74ad32a2bf218
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>

diff --git a/tools/python/xen/xend/XendConfig.py 
b/tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py
+++ b/tools/python/xen/xend/XendConfig.py
@@ -1274,6 +1274,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 --git a/tools/python/xen/xend/XendDomainInfo.py 
b/tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py
+++ b/tools/python/xen/xend/XendDomainInfo.py
@@ -569,8 +569,25 @@ class XendDomainInfo:
         if not found:
             log.debug("Could not find the device %s", devid)
             return None
+
         log.debug("devid = %s", devid)
-        return self.getDeviceController(deviceClass).destroyDevice(devid, 
force)
+
+        dev_control = self.getDeviceController(deviceClass)
+        dev_uuid = dev_control.readBackend(devid, 'uuid')
+
+        ret = None
+
+        try:
+            ret = dev_control.destroyDevice(devid, force)
+        except EnvironmentError:
+            # We failed to detach the device
+            raise VmError("Failed to detach device %d" % devid)
+
+        # 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):
@@ -583,7 +600,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 --git a/tools/python/xen/xend/server/DevController.py 
b/tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py
+++ b/tools/python/xen/xend/server/DevController.py
@@ -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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] Make device detach wait for detach to complete, john . levon <=