mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
domain: Use virtinst for hostdev listing
This commit is contained in:
parent
32e1f41de8
commit
6eee79a88f
@ -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():
|
||||
|
@ -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()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user