xm on xenapi: Add missing support for creating pci-assigned domains
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 31 Jul 2008 12:30:59 +0000 (13:30 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 31 Jul 2008 12:30:59 +0000 (13:30 +0100)
Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@ab.jp.nec.com>
tools/python/xen/xm/create.dtd
tools/python/xen/xm/xenapi_create.py

index efb3cbfd3e929de9160d9bbc533aa72cb376580a..0d9b52405a74bac69956e2536e8e2dc915adfbf9 100644 (file)
@@ -39,6 +39,7 @@
                  vbd*,
                  vif*,
                  vtpm*,
+                 pci*,
                  console*,
                  platform*,
                  vcpu_param*,
 <!ELEMENT vtpm   (name*)>
 <!ATTLIST vtpm   backend         CDATA #REQUIRED>
 
+<!ELEMENT pci    EMPTY>
+<!ATTLIST pci    domain          CDATA #REQUIRED
+                 bus             CDATA #REQUIRED
+                 slot            CDATA #REQUIRED
+                 func            CDATA #REQUIRED
+                 vslt            CDATA #IMPLIED>
+
 <!ELEMENT console (other_config*)>
 <!ATTLIST console protocol       (vt100|rfb|rdp) #REQUIRED>
 
index 7d834f37a1c22da084595e41a5736bb3437f2d4a..ceac76f1e11831c1a27c6814c23059d454f8791f 100644 (file)
@@ -369,6 +369,12 @@ class xenapi_create:
 
             self.create_consoles(vm_ref, consoles)
 
+            # Now create pcis
+
+            pcis = vm.getElementsByTagName("pci")
+
+            self.create_pcis(vm_ref, pcis)
+
             return vm_ref
         except:
             server.xenapi.VM.destroy(vm_ref)
@@ -493,6 +499,39 @@ class xenapi_create:
 
         return server.xenapi.console.create(console_record)
 
+    def create_pcis(self, vm_ref, pcis):
+        log(DEBUG, "create_pcis")
+        return map(lambda pci: self.create_pci(vm_ref, pci), pcis)
+
+    def create_pci(self, vm_ref, pci):
+        log(DEBUG, "create_pci")
+
+        domain = int(pci.attributes["domain"].value, 16)
+        bus = int(pci.attributes["bus"].value, 16)
+        slot = int(pci.attributes["slot"].value, 16)
+        func = int(pci.attributes["func"].value, 16)
+        name = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+
+        target_ref = None
+        for ppci_ref in server.xenapi.PPCI.get_all():
+            if name == server.xenapi.PPCI.get_name(ppci_ref):
+                target_ref = ppci_ref
+                break
+        if target_ref is None:
+            log(DEBUG, "create_pci: pci device not found")
+            return None
+
+        dpci_record = {
+            "VM":
+                vm_ref,
+            "PPCI":
+                target_ref,
+            "hotplug_slot":
+                int(pci.attributes["func"].value, 16)
+        }
+
+        return server.xenapi.DPCI.create(dpci_record)
+
 def get_child_by_name(exp, childname, default = None):
     try:
         return [child for child in sxp.children(exp)
@@ -521,6 +560,9 @@ class sxp2xml:
         vfbs_sxp = map(lambda x: x[1], [device for device in devices
                                         if device[1][0] == "vfb"])
 
+        pcis_sxp = map(lambda x: x[1], [device for device in devices
+                                        if device[1][0] == "pci"])
+
         # Create XML Document
         
         impl = getDOMImplementation()
@@ -656,6 +698,12 @@ class sxp2xml:
 
         map(vm.appendChild, vtpms)
 
+        # And now the pcis
+
+        pcis = self.extract_pcis(pcis_sxp, document)
+
+        map(vm.appendChild, pcis)
+
         # Last but not least the consoles...
 
         consoles = self.extract_consoles(image, document)
@@ -823,7 +871,28 @@ class sxp2xml:
 
         return vfb
 
-    _eths = -1
+    def extract_pcis(self, pcis_sxp, document):
+
+        pcis = []
+
+        for pci_sxp in pcis_sxp:
+            for dev_sxp in sxp.children(pci_sxp, "dev"):
+                pci = document.createElement("pci")
+
+                pci.attributes["domain"] \
+                    = get_child_by_name(dev_sxp, "domain", "0")
+                pci.attributes["bus"] \
+                    = get_child_by_name(dev_sxp, "bus", "0")
+                pci.attributes["slot"] \
+                    = get_child_by_name(dev_sxp, "slot", "0")
+                pci.attributes["func"] \
+                    = get_child_by_name(dev_sxp, "func", "0")
+                pci.attributes["vslt"] \
+                    = get_child_by_name(dev_sxp, "vslt", "0")
+
+                pcis.append(pci)
+
+        return pcis
 
     def mk_other_config(self, key, value, document):
         other_config = document.createElement("other_config")
@@ -916,6 +985,8 @@ class sxp2xml:
  
         return platform_configs
     
+    _eths = -1
+
     def getFreshEthDevice(self):
         self._eths += 1
         return "eth%i" % self._eths