domain: Use virtinst for hostdev listing

This commit is contained in:
Cole Robinson 2010-09-07 12:09:48 -04:00
parent 32e1f41de8
commit 6eee79a88f
2 changed files with 135 additions and 173 deletions

View File

@ -108,12 +108,116 @@ def prettyify_disk(devtype, bus, idx):
return "%s %s" % (ret, idx)
def safeint(val, fmt="%.3d"):
try:
int(val)
except:
return str(val)
return fmt % int(val)
def prettyify_bytes(val):
if val > (1024*1024*1024):
return "%2.2f GB" % (val/(1024.0*1024.0*1024.0))
else:
return "%2.2f MB" % (val/(1024.0*1024.0))
def build_hostdev_label(hostdev):
# String shown in the devices details section
srclabel = ""
# String shown in the VMs hardware list
hwlabel = ""
typ = hostdev.type
vendor = hostdev.vendor
product = hostdev.product
addrbus = hostdev.bus
addrdev = hostdev.device
addrslt = hostdev.slot
addrfun = hostdev.function
addrdom = hostdev.domain
def dehex(val):
if val.startswith("0x"):
val = val[2:]
return val
hwlabel = typ.upper()
srclabel = typ.upper()
if vendor and product:
# USB by vendor + product
devstr = " %s:%s" % (dehex(vendor), dehex(product))
srclabel += devstr
hwlabel += devstr
elif addrbus and addrdev:
# USB by bus + dev
srclabel += (" Bus %s Device %s" %
(safeint(addrbus), safeint(addrdev)))
hwlabel += " %s:%s" % (safeint(addrbus), safeint(addrdev))
elif addrbus and addrslt and addrfun and addrdom:
# PCI by bus:slot:function
devstr = (" %s:%s:%s.%s" %
(dehex(addrdom), dehex(addrbus),
dehex(addrslt), dehex(addrfun)))
srclabel += devstr
hwlabel += devstr
return srclabel, hwlabel
def lookup_nodedev(vmmconn, hostdev):
def intify(val, do_hex=False):
try:
if do_hex:
return int(val or '0x00', 16)
else:
return int(val)
except:
return -1
def attrVal(node, attr):
if not hasattr(node, attr):
return None
return getattr(node, attr)
devtype = hostdev.type
vendor_id = hostdev.vendor or -1
product_id = hostdev.product or -1
device = intify(hostdev.device, True)
bus = intify(hostdev.bus, True)
domain = intify(hostdev.domain, True)
func = intify(hostdev.function, True)
slot = intify(hostdev.slot, True)
found_dev = None
# For USB we want a device, not a bus
if devtype == 'usb':
devtype = 'usb_device'
devs = vmmconn.get_devices(devtype, None)
for dev in devs:
# Try to get info from {product|vendor}_id
if (attrVal(dev, "product_id") == product_id and
attrVal(dev, "vendor_id") == vendor_id):
found_dev = dev
break
else:
# Try to get info from bus/addr
dev_id = intify(attrVal(dev, "device"))
bus_id = intify(attrVal(dev, "bus"))
dom_id = intify(attrVal(dev, "domain"))
func_id = intify(attrVal(dev, "function"))
slot_id = intify(attrVal(dev, "slot"))
if ((dev_id == device and bus_id == bus) or
(dom_id == domain and func_id == func and
bus_id == bus and slot_id == slot)):
found_dev = dev
break
return found_dev
class vmmDetails(gobject.GObject):
__gsignals__ = {
"action-show-console": (gobject.SIGNAL_RUN_FIRST,
@ -1964,77 +2068,22 @@ class vmmDetails(gobject.GObject):
self.window.get_widget("char-source-path").set_text(src_path or "-")
def refresh_hostdev_page(self):
hostdevinfo = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not hostdevinfo:
hostdev = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not hostdev:
return
def intify(val, do_hex=False):
try:
if do_hex:
return int(val or '0x00', 16)
else:
return int(val)
except:
return -1
devtype = hostdev.type
pretty_name = None
nodedev = lookup_nodedev(self.vm.get_connection(), hostdev)
if nodedev:
pretty_name = nodedev.pretty_name()
def attrVal(node, attr):
if not hasattr(node, attr):
return None
return getattr(node, attr)
devinfo = hostdevinfo[6]
vendor_id = -1
product_id = -1
device = 0
bus = 0
domain = 0
func = 0
slot = 0
if devinfo.get("vendor") and devinfo.get("product"):
vendor_id = devinfo["vendor"].get("id") or -1
product_id = devinfo["product"].get("id") or -1
elif devinfo.get("address"):
device = intify(devinfo["address"].get("device"), True)
bus = intify(devinfo["address"].get("bus"), True)
domain = intify(devinfo["address"].get("domain"), True)
func = intify(devinfo["address"].get("function"), True)
slot = intify(devinfo["address"].get("slot"), True)
typ = devinfo.get("type")
# For USB we want a device, not a bus
if typ == 'usb':
typ = 'usb_device'
dev_pretty_name = None
devs = self.vm.get_connection().get_devices( typ, None )
# Get device pretty name
for dev in devs:
# Try to get info from {product|vendor}_id
if (attrVal(dev, "product_id") == product_id and
attrVal(dev, "vendor_id") == vendor_id):
dev_pretty_name = dev.pretty_name()
break
else:
# Try to get info from bus/addr
dev_id = intify(attrVal(dev, "device"))
bus_id = intify(attrVal(dev, "bus"))
dom_id = intify(attrVal(dev, "domain"))
func_id = intify(attrVal(dev, "function"))
slot_id = intify(attrVal(dev, "slot"))
if ((dev_id == device and bus_id == bus) or
(dom_id == domain and func_id == func and
bus_id == bus and slot_id == slot)):
dev_pretty_name = dev.pretty_name()
break
devlabel = "<b>Physical %s Device</b>" % hostdevinfo[4].upper()
if not pretty_name:
pretty_name = build_hostdev_label(hostdev)[0] or "-"
devlabel = "<b>Physical %s Device</b>" % devtype.upper()
self.window.get_widget("hostdev-title").set_markup(devlabel)
self.window.get_widget("hostdev-source").set_text(dev_pretty_name or
"-")
self.window.get_widget("hostdev-source").set_text(pretty_name)
def refresh_video_page(self):
vid = self.get_hw_selection(HW_LIST_COL_DEVICE)
@ -2233,18 +2282,17 @@ class vmmDetails(gobject.GObject):
"device_serial", key)
# Populate host devices
for hostdevinfo in self.vm.get_hostdev_devices():
key = str(hostdevinfo[1])
devtype = hostdevinfo[4]
label = hostdevinfo[2]
for hostdev in self.vm.get_hostdev_devices():
key = str(hostdev.index)
devtype = hostdev.type
label = build_hostdev_label(hostdev)[1]
currentHostdevs[key] = 1
if devtype == "usb":
icon = "device_usb"
else:
icon = "device_pci"
update_hwlist(HW_LIST_TYPE_HOSTDEV, hostdevinfo, label,
icon, key)
update_hwlist(HW_LIST_TYPE_HOSTDEV, hostdev, label, icon, key)
# Populate video devices
for vid in self.vm.get_video_devices():

View File

@ -31,13 +31,6 @@ from virtinst import VirtualDevice
from virtManager.libvirtobject import vmmLibvirtObject
def safeint(val, fmt="%.3d"):
try:
int(val)
except:
return str(val)
return fmt % int(val)
def disk_type_to_xen_driver_name(disk_type):
if disk_type == "block":
return "phy"
@ -425,7 +418,7 @@ class vmmDomainBase(vmmLibvirtObject):
for dev in devs:
dev.index = count
count += 1
return devs
def get_char_devices(self):
@ -464,99 +457,27 @@ class vmmDomainBase(vmmLibvirtObject):
for dev in devs:
dev.index = count
count += 1
return devs
def get_hostdev_devices(self):
def _parse_hostdev_devs(ctx):
hostdevs = []
devs = ctx.xpathEval("/domain/devices/hostdev")
count = 0
device_type = "hostdev"
guest = self._get_guest()
devs = guest.get_devices(device_type)
count = 0
for dev in devs:
dev.index = count
count += 1
for dev in devs:
vendor = None
product = None
addrbus = None
addrdev = None
unique = {}
# String shown in the devices details section
srclabel = ""
# String shown in the VMs hardware list
hwlabel = ""
# [device type, unique, hwlist label, hostdev mode,
# hostdev type, source desc label]
#hostdevs.append(["hostdev", index, hwlabel, mode, typ,
# srclabel, unique])
def dehex(val):
if val.startswith("0x"):
val = val[2:]
return val
def set_uniq(baseent, propname, node):
val = node.prop(propname)
if not unique.has_key(baseent):
unique[baseent] = {}
unique[baseent][propname] = val
return val
return devs
mode = dev.prop("mode")
typ = dev.prop("type")
unique["type"] = typ
hwlabel = typ.upper()
srclabel = typ.upper()
for node in dev.children:
if node.name == "source":
for child in node.children:
if child.name == "address":
addrbus = set_uniq("address", "bus", child)
# For USB
addrdev = set_uniq("address", "device", child)
# For PCI
addrdom = set_uniq("address", "domain", child)
addrslt = set_uniq("address", "slot", child)
addrfun = set_uniq("address", "function", child)
elif child.name == "vendor":
vendor = set_uniq("vendor", "id", child)
elif child.name == "product":
product = set_uniq("product", "id", child)
if vendor and product:
# USB by vendor + product
devstr = " %s:%s" % (dehex(vendor), dehex(product))
srclabel += devstr
hwlabel += devstr
elif addrbus and addrdev:
# USB by bus + dev
srclabel += " Bus %s Device %s" % \
(safeint(addrbus), safeint(addrdev))
hwlabel += " %s:%s" % (safeint(addrbus), safeint(addrdev))
elif addrbus and addrslt and addrfun and addrdom:
# PCI by bus:slot:function
devstr = " %s:%s:%s.%s" % \
(dehex(addrdom), dehex(addrbus),
dehex(addrslt), dehex(addrfun))
srclabel += devstr
hwlabel += devstr
else:
# If we can't determine source info, skip these
# device since we have no way to determine uniqueness
continue
index = count
count += 1
# [device type, unique, hwlist label, hostdev mode,
# hostdev type, source desc label]
hostdevs.append(["hostdev", index, hwlabel, mode, typ,
srclabel, unique])
return hostdevs
return self._parse_device_xml(_parse_hostdev_devs)
def get_watchdog_devices(self):
device_type = "watchdog"
@ -566,16 +487,9 @@ class vmmDomainBase(vmmLibvirtObject):
for dev in devs:
dev.index = count
count += 1
return devs
def _parse_device_xml(self, parse_function):
def parse_wrap_func(doc, ctx):
return parse_function(ctx)
xml = self.get_xml()
return util.xml_parse_wrapper(xml, parse_wrap_func)
def _get_device_xml(self, dev_type, dev_id_info):
vmxml = self.get_xml()