ia64/xen-unstable

view tools/python/xen/xend/XendDPCI.py @ 19719:728eb34bbfcc

xm, xend: xen-api: DPCI.get_hotplug_slot() returns a decimal

xm uses the following code to read pci information using Xen API:

ppci_ref =3D server.xenapi.DPCI.get_PPCI(dpci_ref)
ppci_record =3D server.xenapi.PPCI.get_record(ppci_ref)
dev =3D {
"domain": int(ppci_record["domain"]),
"bus": int(ppci_record["bus"]),
"slot": int(ppci_record["slot"]),
"func": int(ppci_record["func"]),
"vslot": int(server.xenapi.DPCI.get_hotplug_slot(dpci_ref))
}

As the domain, bus, slot and func values are returned as string
representations of decimal, it makes sense for get_hotplug_slot() to
also return string representations of decimal.

As it is, the int() conversion will break cause xm to fail with
an error if the vslot is in the range 0xa-0xf or 0x1a-0x1f.

$ xm pci-list debian
Error: Invalid argument.

And the int() conversion will return the wrong value if
the vslot is in the range 0x10-0x19.

This patch also alters XendDPCI to store hotplug_vslot as an integer
rather than a string. This is consitent with the way other
values are stored inside XendDPCI.

get_hotplug_slot() returning a string is not consistent
with other calls inside XendDPCI, which return integers.

Signed-off-by: Simon Horman <horms@verge.net.au>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:40:24 2009 +0100 (2009-06-04)
parents 989bd3f2fd72
children
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (c) 2008 NEC Corporation
16 # Yosuke Iwamatsu <y-iwamatsu at ab jp nec com>
17 #============================================================================
19 from xen.xend.XendBase import XendBase
20 from xen.xend.XendPPCI import XendPPCI
21 from xen.xend import XendAPIStore
22 from xen.xend import uuid as genuuid
24 import XendDomain, XendNode
26 from XendError import *
27 from XendTask import XendTask
28 from XendLogging import log
30 class XendDPCI(XendBase):
31 """Representation of a passthrough PCI device."""
33 def getClass(self):
34 return "DPCI"
36 def getAttrRO(self):
37 attrRO = ['virtual_domain',
38 'virtual_bus',
39 'virtual_slot',
40 'virtual_func',
41 'virtual_name',
42 'VM',
43 'PPCI',
44 'hotplug_slot',
45 'options']
46 return XendBase.getAttrRO() + attrRO
48 def getAttrRW(self):
49 attrRW = []
50 return XendBase.getAttrRW() + attrRW
52 def getAttrInst(self):
53 attrInst = ['VM',
54 'PPCI',
55 'hotplug_slot']
56 return XendBase.getAttrInst() + attrInst
58 def getMethods(self):
59 methods = ['destroy']
60 return XendBase.getMethods() + methods
62 def getFuncs(self):
63 funcs = ['create']
64 return XendBase.getFuncs() + funcs
66 getClass = classmethod(getClass)
67 getAttrRO = classmethod(getAttrRO)
68 getAttrRW = classmethod(getAttrRW)
69 getAttrInst = classmethod(getAttrInst)
70 getMethods = classmethod(getMethods)
71 getFuncs = classmethod(getFuncs)
73 def create(self, dpci_struct):
75 # Check if VM is valid
76 xendom = XendDomain.instance()
77 if not xendom.is_valid_vm(dpci_struct['VM']):
78 raise InvalidHandleError('VM', dpci_struct['VM'])
79 dom = xendom.get_vm_by_uuid(dpci_struct['VM'])
81 # Check if PPCI is valid
82 xennode = XendNode.instance()
83 ppci_uuid = xennode.get_ppci_by_uuid(dpci_struct['PPCI'])
84 if not ppci_uuid:
85 raise InvalidHandleError('PPCI', dpci_struct['PPCI'])
86 for existing_dpci in XendAPIStore.get_all('DPCI'):
87 if ppci_uuid == existing_dpci.get_PPCI():
88 raise DirectPCIError("Device is in use")
90 # Assign PPCI to VM
91 try:
92 dpci_ref = XendTask.log_progress(0, 100, dom.create_dpci,
93 dpci_struct)
94 except XendError, e:
95 raise DirectPCIError("Failed to assign device")
97 # TODO: Retrive virtual pci device infomation.
99 return dpci_ref
101 create = classmethod(create)
103 def get_by_VM(cls, VM_ref):
104 result = []
105 for dpci in XendAPIStore.get_all("DPCI"):
106 if dpci.get_VM() == VM_ref:
107 result.append(dpci.get_uuid())
108 return result
110 get_by_VM = classmethod(get_by_VM)
112 def __init__(self, uuid, record):
113 XendBase.__init__(self, uuid, record)
115 self.virtual_domain = -1
116 self.virtual_bus = -1
117 self.virtual_slot = -1
118 self.virtual_func = -1
120 self.VM = record['VM']
121 self.PPCI = record['PPCI']
122 self.hotplug_slot = int(record['hotplug_slot'], 16)
123 if 'options' in record.keys():
124 self.options = record['options']
126 def destroy(self):
127 xendom = XendDomain.instance()
128 dom = xendom.get_vm_by_uuid(self.get_VM())
129 if not dom:
130 raise InvalidHandleError("VM", self.get_VM())
131 XendTask.log_progress(0, 100, dom.destroy_dpci, self.get_uuid())
133 def get_virtual_domain(self):
134 return self.virtual_domain
136 def get_virtual_bus(self):
137 return self.virtual_bus
139 def get_virtual_slot(self):
140 return self.virtual_slot
142 def get_virtual_func(self):
143 return self.virtual_func
145 def get_virtual_name(self):
146 return "%04x:%02x:%02x.%01x" % (self.virtual_domain, self.virtual_bus,
147 self.virtual_slot, self.virtual_func)
149 def get_VM(self):
150 return self.VM
152 def get_PPCI(self):
153 return self.PPCI
155 def get_hotplug_slot(self):
156 return "%d" % self.hotplug_slot
158 def get_options(self):
159 return self.options