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] xend: Fix xm pci-attach/detach for inacti

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xend: Fix xm pci-attach/detach for inactive managed domains
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 09 Apr 2009 23:00:28 -0700
Delivery-date: Thu, 09 Apr 2009 23:01:48 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/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 Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1239273314 -3600
# Node ID 72d4c5c83508a21293a52dfe987fcd988e3376d1
# Parent  0b9b6d5a61c1822452fbf370e1e2fa936adf2213
xend: Fix xm pci-attach/detach for inactive managed domains

Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
---
 tools/python/xen/xend/XendDomainInfo.py |  154 ++++++++++++++++++++++----------
 1 files changed, 106 insertions(+), 48 deletions(-)

diff -r 0b9b6d5a61c1 -r 72d4c5c83508 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py   Thu Apr 09 09:59:16 2009 +0100
+++ b/tools/python/xen/xend/XendDomainInfo.py   Thu Apr 09 11:35:14 2009 +0100
@@ -685,31 +685,39 @@ class XendDomainInfo:
         # co-assignment devices hasn't been assigned, or has been assigned to
         # domN.
         coassignment_list = pci_device.find_coassigned_devices()
-        assigned_pci_device_str_list = get_assigned_pci_devices(self.domid)
+        assigned_pci_device_str_list = self._get_assigned_pci_devices()
         for pci_str in coassignment_list:
             (domain, bus, dev, func) = parse_pci_name(pci_str) 
             dev_str =  '0x%x,0x%x,0x%x,0x%x' % (domain, bus, dev, func)
             if xc.test_assign_device(0, dev_str) == 0:
                 continue
             if not pci_str in assigned_pci_device_str_list:
-                raise VmError(('pci: failed to pci-attach %s to dom%d" + \
+                raise VmError(("pci: failed to pci-attach %s to domain %s" + \
                     " because one of its co-assignment device %s has been" + \
-                    " assigned to other domain.' \
-                    )% (pci_device.name, self.domid, pci_str))
-
-        opts = ''
-        if 'opts' in new_dev and len(new_dev['opts']) > 0:
-            config_opts = new_dev['opts']
-            config_opts = map(lambda (x, y): x+'='+y, config_opts)
-            opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
-
-        bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
+                    " assigned to other domain." \
+                    )% (pci_device.name, self.info['name_label'], pci_str))
+
+        if self.domid is not None:
+            opts = ''
+            if 'opts' in new_dev and len(new_dev['opts']) > 0:
+                config_opts = new_dev['opts']
+                config_opts = map(lambda (x, y): x+'='+y, config_opts)
+                opts = ',' + reduce(lambda x, y: x+','+y, config_opts)
+
+            bdf_str = "%s:%s:%s.%s%s@%s" % (new_dev['domain'],
                 new_dev['bus'],
                 new_dev['slot'],
                 new_dev['func'],
                 opts,
                 new_dev['vslot'])
-        self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
+            self.image.signalDeviceModel('pci-ins', 'pci-inserted', bdf_str)
+
+            vslot = xstransact.Read("/local/domain/0/device-model/%i/parameter"
+                                    % self.getDomid())
+        else:
+            vslot = new_dev['vslot']
+
+        return vslot
 
 
     def device_create(self, dev_config):
@@ -788,10 +796,8 @@ class XendDomainInfo:
         if self.info.is_hvm():
             if pci_state == 'Initialising':
                 # HVM PCI device attachment
-                self.hvm_pci_device_create(dev_config)
+                vslot = self.hvm_pci_device_create(dev_config)
                 # Update vslot
-                vslot = 
xstransact.Read("/local/domain/0/device-model/%i/parameter"
-                                        % self.getDomid())
                 dev['vslot'] = vslot
                 for n in sxp.children(pci_dev):
                     if(n[0] == 'vslot'):
@@ -825,35 +831,66 @@ class XendDomainInfo:
             self.device_create(dev_sxp)
             return True
 
-        # use DevController.reconfigureDevice to change device config
-        dev_control = self.getDeviceController(dev_class)
-        dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
-        if not self.info.is_hvm():
-            # in PV case, wait until backend state becomes connected.
-            dev_control.waitForDevice_reconfigure(devid)
-        num_devs = dev_control.cleanupDevice(devid)
-
-        # update XendConfig with new device info
-        if dev_uuid:
-            new_dev_sxp = dev_control.configuration(devid)
+        if self.domid is not None:
+            # use DevController.reconfigureDevice to change device config
+            dev_control = self.getDeviceController(dev_class)
+            dev_uuid = dev_control.reconfigureDevice(devid, dev_config)
+            if not self.info.is_hvm():
+                # in PV case, wait until backend state becomes connected.
+                dev_control.waitForDevice_reconfigure(devid)
+            num_devs = dev_control.cleanupDevice(devid)
+
+            # update XendConfig with new device info
+            if dev_uuid:
+                new_dev_sxp = dev_control.configuration(devid)
+                self.info.device_update(dev_uuid, new_dev_sxp)
+
+            # If there is no device left, destroy pci and remove config.
+            if num_devs == 0:
+                if self.info.is_hvm():
+                    self.destroyDevice('pci', devid, True)
+                    del self.info['devices'][dev_uuid]
+                    platform = self.info['platform']
+                    orig_dev_num = len(platform['pci'])
+                    # TODO: can use this to keep some info to ask high level
+                    # management tools to hot insert a new passthrough dev
+                    # after migration
+                    if orig_dev_num != 0:
+                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
+                        platform['pci'] = []
+                else:
+                    self.destroyDevice('pci', devid)
+                    del self.info['devices'][dev_uuid]
+        else:
+            new_dev_sxp = ['pci']
+            for cur_dev in sxp.children(existing_dev_info, 'dev'):
+                if pci_state == 'Closing':
+                    if int(dev['domain'], 16) == int(sxp.child_value(cur_dev, 
'domain'), 16) and \
+                       int(dev['bus'], 16) == int(sxp.child_value(cur_dev, 
'bus'), 16) and \
+                       int(dev['slot'], 16) == int(sxp.child_value(cur_dev, 
'slot'), 16) and \
+                       int(dev['func'], 16) == int(sxp.child_value(cur_dev, 
'func'), 16):
+                        continue
+                new_dev_sxp.append(cur_dev)
+
+            if pci_state == 'Initialising':
+                for new_dev in sxp.children(dev_sxp, 'dev'):
+                    new_dev_sxp.append(new_dev)
+
+            dev_uuid = sxp.child_value(existing_dev_info, 'uuid')
             self.info.device_update(dev_uuid, new_dev_sxp)
 
-        # If there is no device left, destroy pci and remove config.
-        if num_devs == 0:
-            if self.info.is_hvm():
-                self.destroyDevice('pci', devid, True)
+            # If there is only 'vscsi' in new_dev_sxp, remove the config.
+            if len(sxp.children(new_dev_sxp, 'dev')) == 0:
                 del self.info['devices'][dev_uuid]
-                platform = self.info['platform']
-                orig_dev_num = len(platform['pci'])
-                # TODO: can use this to keep some info to ask high level
-                # management tools to hot insert a new passthrough dev
-                # after migration
-                if orig_dev_num != 0:
-                    #platform['pci'] = ["%dDEVs" % orig_dev_num]
-                    platform['pci'] = []
-            else:
-                self.destroyDevice('pci', devid)
-                del self.info['devices'][dev_uuid]
+                if self.info.is_hvm():
+                    platform = self.info['platform']
+                    orig_dev_num = len(platform['pci'])
+                    # TODO: can use this to keep some info to ask high level
+                    # management tools to hot insert a new passthrough dev
+                    # after migration
+                    if orig_dev_num != 0:
+                        #platform['pci'] = ["%dDEVs" % orig_dev_num]
+                        platform['pci'] = []
 
         xen.xend.XendDomain.instance().managed_config_save(self)
 
@@ -1054,7 +1091,7 @@ class XendDomainInfo:
             raise VmError("Device @ vslot 0x%x doesn't exist." % (vslot))
 
         if vslot == AUTO_PHP_SLOT:
-            raise VmError("Device @ vslot 0x%x do not support hotplug." % 
(vslot))
+            raise VmError("Device @ vslot 0x%x doesn't support hotplug." % 
(vslot))
 
         # Check the co-assignment.
         # To pci-detach a device D from domN, we should ensure: for each DD in 
the
@@ -1072,19 +1109,20 @@ class XendDomainInfo:
                     "parse it's resources - "+str(e))
         coassignment_list = pci_device.find_coassigned_devices()
         coassignment_list.remove(pci_device.name)
-        assigned_pci_device_str_list = get_assigned_pci_devices(self.domid)
+        assigned_pci_device_str_list = self._get_assigned_pci_devices()
         for pci_str in coassignment_list:
             if pci_str in assigned_pci_device_str_list:
-                raise VmError(('pci: failed to pci-detach %s from dom%d" + \
+                raise VmError(("pci: failed to pci-detach %s from domain %s" + 
\
                     " because one of its co-assignment device %s is still " + \
-                    " assigned to the domain.' \
-                    )% (pci_device.name, self.domid, pci_str))
+                    " assigned to the domain." \
+                    )% (pci_device.name, self.info['name_label'], pci_str))
 
 
         bdf_str = "%s:%s:%s.%s" % (x['domain'], x['bus'], x['slot'], x['func'])
         log.info("hvm_destroyPCIDevice:%s:%s!", x, bdf_str)
 
-        self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
+        if self.domid is not None:
+            self.image.signalDeviceModel('pci-rem', 'pci-removed', bdf_str)
 
         return 0
 
@@ -1233,6 +1271,26 @@ class XendDomainInfo:
             if devid == int(sxp.child_value(devs[0], 'devid')):
                 return dev_info
         return None
+
+    def _get_assigned_pci_devices(self, devid = 0):
+        if self.domid is not None:
+            return get_assigned_pci_devices(self.domid)
+
+        dev_str_list = []
+        dev_info = self._getDeviceInfo_pci(devid)
+        if dev_info is None:
+            return dev_str_list
+        dev_uuid = sxp.child_value(dev_info, 'uuid')
+        pci_conf = self.info['devices'][dev_uuid][1]
+        pci_devs = pci_conf['devs']
+        for pci_dev in pci_devs:
+            domain = int(pci_dev['domain'], 16)
+            bus = int(pci_dev['bus'], 16)
+            slot = int(pci_dev['slot'], 16)
+            func = int(pci_dev['func'], 16)
+            dev_str = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+            dev_str_list = dev_str_list + [dev_str]
+        return dev_str_list 
 
     def setMemoryTarget(self, target):
         """Set the memory target of this domain.

_______________________________________________
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] xend: Fix xm pci-attach/detach for inactive managed domains, Xen patchbot-unstable <=