2013-03-18 05:06:52 +08:00
|
|
|
#
|
2013-10-28 04:59:46 +08:00
|
|
|
# Copyright 2009, 2013 Red Hat, Inc.
|
2013-03-18 05:06:52 +08:00
|
|
|
# Cole Robinson <crobinso@redhat.com>
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
2013-10-28 04:59:47 +08:00
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
2013-03-18 05:06:52 +08:00
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
|
|
# MA 02110-1301 USA.
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
2014-09-13 03:59:22 +08:00
|
|
|
from .xmlbuilder import XMLBuilder
|
2014-09-18 02:56:52 +08:00
|
|
|
from .xmlbuilder import XMLProperty as _XMLProperty
|
2013-08-09 08:47:17 +08:00
|
|
|
|
|
|
|
|
2014-09-18 02:56:52 +08:00
|
|
|
class XMLProperty(_XMLProperty):
|
|
|
|
_track = False
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2014-09-16 23:44:21 +08:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
class NodeDevice(XMLBuilder):
|
|
|
|
CAPABILITY_TYPE_SYSTEM = "system"
|
|
|
|
CAPABILITY_TYPE_NET = "net"
|
|
|
|
CAPABILITY_TYPE_PCI = "pci"
|
|
|
|
CAPABILITY_TYPE_USBDEV = "usb_device"
|
|
|
|
CAPABILITY_TYPE_USBBUS = "usb"
|
|
|
|
CAPABILITY_TYPE_STORAGE = "storage"
|
|
|
|
CAPABILITY_TYPE_SCSIBUS = "scsi_host"
|
|
|
|
CAPABILITY_TYPE_SCSIDEV = "scsi"
|
|
|
|
|
|
|
|
(HOSTDEV_ADDR_TYPE_LIBVIRT,
|
|
|
|
HOSTDEV_ADDR_TYPE_PCI,
|
|
|
|
HOSTDEV_ADDR_TYPE_USB_BUSADDR,
|
|
|
|
HOSTDEV_ADDR_TYPE_USB_VENPRO) = range(1, 5)
|
|
|
|
|
|
|
|
@staticmethod
|
2014-09-20 23:30:24 +08:00
|
|
|
def lookupNodedevFromString(conn, idstring):
|
2013-09-23 06:13:24 +08:00
|
|
|
"""
|
|
|
|
Convert the passed libvirt node device name to a NodeDevice
|
|
|
|
instance, with proper error reporting. If the name is name is not
|
|
|
|
found, we will attempt to parse the name as would be passed to
|
|
|
|
devAddressToNodeDev
|
2013-05-14 04:45:51 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
@param conn: libvirt.virConnect instance to perform the lookup on
|
2014-09-20 23:30:24 +08:00
|
|
|
@param idstring: libvirt node device name to lookup, or address
|
|
|
|
of the form:
|
|
|
|
- bus.addr (ex. 001.003 for a usb device)
|
|
|
|
- vendor:product (ex. 0x1234:0x5678 for a usb device
|
|
|
|
- (domain:)bus:slot.func (ex. 00:10.0 for a pci device)
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
@rtype: L{NodeDevice} instance
|
|
|
|
"""
|
2013-10-06 22:08:04 +08:00
|
|
|
if not conn.check_support(conn.SUPPORT_CONN_NODEDEV):
|
2013-09-23 06:13:24 +08:00
|
|
|
raise ValueError(_("Connection does not support host device "
|
|
|
|
"enumeration."))
|
|
|
|
|
2014-09-20 23:30:24 +08:00
|
|
|
# First try and see if this is a libvirt nodedev name
|
|
|
|
for nodedev in conn.fetch_all_nodedevs():
|
|
|
|
if nodedev.name == idstring:
|
|
|
|
return nodedev
|
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
try:
|
2014-09-20 23:30:24 +08:00
|
|
|
return _AddressStringToNodedev(conn, idstring)
|
|
|
|
except:
|
|
|
|
logging.debug("Error looking up nodedev from idstring=%s",
|
|
|
|
idstring, exc_info=True)
|
|
|
|
raise RuntimeError(_("Did not find node device matching '%s'" %
|
|
|
|
idstring))
|
2013-09-23 06:13:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def parse(conn, xml):
|
|
|
|
tmpdev = NodeDevice(conn, parsexml=xml, allow_node_instantiate=True)
|
|
|
|
cls = _typeToDeviceClass(tmpdev.device_type)
|
|
|
|
return cls(conn, parsexml=xml, allow_node_instantiate=True)
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
instantiate = kwargs.pop("allow_node_instantiate", False)
|
|
|
|
if self.__class__ is NodeDevice and not instantiate:
|
|
|
|
raise RuntimeError("Can not instantiate NodeDevice directly")
|
2013-09-28 06:06:39 +08:00
|
|
|
|
|
|
|
self.addr_type = None
|
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
XMLBuilder.__init__(self, *args, **kwargs)
|
|
|
|
|
|
|
|
_XML_ROOT_NAME = "device"
|
|
|
|
|
|
|
|
name = XMLProperty("./name")
|
|
|
|
parent = XMLProperty("./parent")
|
|
|
|
device_type = XMLProperty("./capability/@type")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2013-03-18 05:06:52 +08:00
|
|
|
"""
|
|
|
|
Use device information to attempt to print a human readable device
|
|
|
|
name.
|
|
|
|
|
|
|
|
@returns: Device description string
|
|
|
|
@rtype C{str}
|
|
|
|
"""
|
|
|
|
return self.name
|
|
|
|
|
2014-09-16 23:44:21 +08:00
|
|
|
def compare_to_hostdev(self, hostdev):
|
|
|
|
ignore = hostdev
|
|
|
|
return False
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class SystemDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
hw_vendor = XMLProperty("./capability/hardware/vendor")
|
|
|
|
hw_version = XMLProperty("./capability/hardware/version")
|
|
|
|
hw_serial = XMLProperty("./capability/hardware/serial")
|
|
|
|
hw_uuid = XMLProperty("./capability/hardware/uuid")
|
|
|
|
|
|
|
|
fw_vendor = XMLProperty("./capability/firmware/vendor")
|
|
|
|
fw_version = XMLProperty("./capability/firmware/version")
|
|
|
|
fw_date = XMLProperty("./capability/firmware/release_date")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2013-03-18 05:06:52 +08:00
|
|
|
desc = _("System")
|
|
|
|
if self.hw_vendor:
|
|
|
|
desc += ": %s" % self.hw_vendor
|
|
|
|
if self.hw_version:
|
|
|
|
desc += " %s" % self.hw_version
|
|
|
|
|
|
|
|
return desc
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class NetDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
interface = XMLProperty("./capability/interface")
|
|
|
|
address = XMLProperty("./capability/address")
|
|
|
|
capability_type = XMLProperty("./capability/capability/@type")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2013-03-18 05:06:52 +08:00
|
|
|
desc = self.name
|
|
|
|
if self.interface:
|
|
|
|
desc = _("Interface %s") % self.interface
|
|
|
|
|
|
|
|
return desc
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class PCIDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
domain = XMLProperty("./capability/domain")
|
|
|
|
bus = XMLProperty("./capability/bus")
|
|
|
|
slot = XMLProperty("./capability/slot")
|
|
|
|
function = XMLProperty("./capability/function")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
product_name = XMLProperty("./capability/product")
|
|
|
|
product_id = XMLProperty("./capability/product/@id")
|
|
|
|
vendor_name = XMLProperty("./capability/vendor")
|
|
|
|
vendor_id = XMLProperty("./capability/vendor/@id")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-10-10 21:41:49 +08:00
|
|
|
iommu_group = XMLProperty("./capability/iommuGroup/@number", is_int=True)
|
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2014-04-15 22:22:33 +08:00
|
|
|
devstr = "%.4X:%.2X:%.2X:%X" % (int(self.domain),
|
|
|
|
int(self.bus),
|
|
|
|
int(self.slot),
|
|
|
|
int(self.function))
|
2014-01-13 03:52:15 +08:00
|
|
|
|
2014-01-13 03:52:33 +08:00
|
|
|
return "%s %s %s" % (devstr, self.vendor_name, self.product_name)
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-09-16 23:44:21 +08:00
|
|
|
def compare_to_hostdev(self, hostdev):
|
|
|
|
if hostdev.type != self.device_type:
|
|
|
|
return False
|
|
|
|
|
|
|
|
h_bus = h_dev = h_dom = h_slot = h_func = None
|
|
|
|
|
|
|
|
h_dom = _intify(hostdev.domain, True)
|
|
|
|
h_bus = _intify(hostdev.bus, True)
|
|
|
|
h_slot = _intify(hostdev.slot, True)
|
|
|
|
h_func = _intify(hostdev.function, True)
|
|
|
|
n_dev = _intify(_attrVal(self, "device"))
|
|
|
|
n_bus = _intify(_attrVal(self, "bus"))
|
|
|
|
n_dom = _intify(_attrVal(self, "domain"))
|
|
|
|
n_func = _intify(_attrVal(self, "function"))
|
|
|
|
n_slot = _intify(_attrVal(self, "slot"))
|
|
|
|
|
|
|
|
if ((n_dev == h_dev and n_bus == h_bus) or
|
|
|
|
(n_dom == h_dom and n_func == h_func and
|
|
|
|
n_bus == h_bus and n_slot == h_slot)):
|
|
|
|
return True
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class USBDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
bus = XMLProperty("./capability/bus")
|
|
|
|
device = XMLProperty("./capability/device")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
product_name = XMLProperty("./capability/product")
|
|
|
|
product_id = XMLProperty("./capability/product/@id")
|
|
|
|
vendor_name = XMLProperty("./capability/vendor")
|
|
|
|
vendor_id = XMLProperty("./capability/vendor/@id")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2014-09-09 20:22:38 +08:00
|
|
|
# Hypervisor may return a rather sparse structure, missing
|
|
|
|
# some ol all stringular descriptions of the device altogether.
|
|
|
|
# Do our best to help user identify the device.
|
|
|
|
|
|
|
|
# Certain devices pad their vendor with trailing spaces,
|
|
|
|
# such as "LENOVO ". It does not look well.
|
|
|
|
product = str(self.product_name).strip()
|
|
|
|
vendor = str(self.vendor_name).strip()
|
|
|
|
|
|
|
|
if product == "":
|
|
|
|
product = str(self.product_id)
|
|
|
|
if vendor == "":
|
|
|
|
# No stringular descriptions altogether
|
|
|
|
vendor = str(self.vendor_id)
|
|
|
|
devstr = "%s:%s" % (vendor, product)
|
|
|
|
else:
|
|
|
|
# Only the vendor is known
|
|
|
|
devstr = "%s %s" % (vendor, product)
|
|
|
|
else:
|
|
|
|
if vendor == "":
|
|
|
|
# Sometimes vendor is left out empty, but product is
|
|
|
|
# already descriptive enough or contains the vendor string:
|
|
|
|
# "Lenovo USB Laser Mouse"
|
|
|
|
devstr = product
|
|
|
|
else:
|
|
|
|
# We know everything. Perfect.
|
|
|
|
devstr = "%s %s" % (vendor, product)
|
|
|
|
|
|
|
|
busstr = "%.3d:%.3d" % (int(self.bus), int(self.device))
|
|
|
|
desc = "%s %s" % (busstr, devstr)
|
2013-03-18 05:06:52 +08:00
|
|
|
return desc
|
|
|
|
|
2014-09-16 23:44:21 +08:00
|
|
|
def compare_to_hostdev(self, hostdev):
|
|
|
|
devtype = hostdev.type
|
|
|
|
if devtype == "usb":
|
|
|
|
devtype = "usb_device"
|
|
|
|
if devtype != self.device_type:
|
|
|
|
return False
|
|
|
|
|
|
|
|
h_vid = h_pid = h_bus = h_dev = None
|
|
|
|
|
|
|
|
h_vid = hostdev.vendor or -1
|
|
|
|
h_pid = hostdev.product or -1
|
|
|
|
h_bus = _intify(hostdev.bus)
|
|
|
|
h_dev = _intify(hostdev.device)
|
|
|
|
|
|
|
|
if ((_attrVal(self, "product_id") == h_pid or h_pid == -1) and
|
|
|
|
(_attrVal(self, "vendor_id") == h_vid or h_vid == -1) and
|
|
|
|
(_intify(_attrVal(self, "bus")) == h_bus or h_bus == -1) and
|
|
|
|
(_intify(_attrVal(self, "device")) == h_dev or h_dev == -1)):
|
|
|
|
return True
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class StorageDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
block = XMLProperty("./capability/block")
|
|
|
|
bus = XMLProperty("./capability/bus")
|
|
|
|
drive_type = XMLProperty("./capability/drive_type")
|
|
|
|
size = XMLProperty("./capability/size", is_int=True)
|
|
|
|
|
|
|
|
model = XMLProperty("./capability/model")
|
|
|
|
vendor = XMLProperty("./capability/vendor")
|
|
|
|
|
|
|
|
hotpluggable = XMLProperty(
|
|
|
|
"./capability/capability[@type='hotpluggable']", is_bool=True)
|
|
|
|
removable = XMLProperty(
|
|
|
|
"./capability/capability[@type='removable']", is_bool=True)
|
|
|
|
|
|
|
|
media_size = XMLProperty(
|
|
|
|
"./capability/capability[@type='removable']/media_size", is_int=True)
|
|
|
|
media_label = XMLProperty(
|
|
|
|
"./capability/capability[@type='removable']/media_label")
|
|
|
|
_media_available = XMLProperty(
|
|
|
|
"./capability/capability[@type='removable']/media_available",
|
|
|
|
is_int=True)
|
|
|
|
def _get_media_available(self):
|
|
|
|
m = self._media_available
|
|
|
|
if m is None:
|
|
|
|
return None
|
|
|
|
return bool(m)
|
|
|
|
def _set_media_available(self, val):
|
|
|
|
self._media_available = val
|
|
|
|
media_available = property(_get_media_available, _set_media_available)
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2014-01-13 03:52:15 +08:00
|
|
|
def pretty_name(self):
|
2013-03-18 05:06:52 +08:00
|
|
|
desc = ""
|
|
|
|
if self.drive_type:
|
|
|
|
desc = self.drive_type
|
|
|
|
|
|
|
|
if self.block:
|
|
|
|
desc = ": ".join((desc, self.block))
|
|
|
|
elif self.model:
|
|
|
|
desc = ": ".join((desc, self.model))
|
|
|
|
else:
|
|
|
|
desc = ": ".join((desc, self.name))
|
|
|
|
return desc
|
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class USBBus(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
number = XMLProperty("./capability/number")
|
|
|
|
classval = XMLProperty("./capability/class")
|
|
|
|
subclass = XMLProperty("./capability/subclass")
|
|
|
|
protocol = XMLProperty("./capability/protocol")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
|
|
|
|
|
|
|
class SCSIDevice(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
host = XMLProperty("./capability/host")
|
|
|
|
bus = XMLProperty("./capability/bus")
|
|
|
|
target = XMLProperty("./capability/target")
|
|
|
|
lun = XMLProperty("./capability/lun")
|
|
|
|
type = XMLProperty("./capability/type")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
class SCSIBus(NodeDevice):
|
2013-09-23 06:13:24 +08:00
|
|
|
host = XMLProperty("./capability/host")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
vport_ops = XMLProperty(
|
|
|
|
"./capability/capability[@type='vport_ops']", is_bool=True)
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-09-23 06:13:24 +08:00
|
|
|
fc_host = XMLProperty(
|
|
|
|
"./capability/capability[@type='fc_host']", is_bool=True)
|
|
|
|
wwnn = XMLProperty("./capability/capability[@type='fc_host']/wwnn")
|
|
|
|
wwpn = XMLProperty("./capability/capability[@type='fc_host']/wwpn")
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2014-09-20 23:30:24 +08:00
|
|
|
def _isAddressString(addrstr):
|
2013-03-18 05:06:52 +08:00
|
|
|
cmp_func = None
|
2013-04-30 22:53:11 +08:00
|
|
|
addr_type = None
|
2013-03-18 05:06:52 +08:00
|
|
|
|
|
|
|
try:
|
|
|
|
# Determine addrstr type
|
|
|
|
if addrstr.count(":") in [1, 2] and addrstr.count("."):
|
2013-09-23 06:13:24 +08:00
|
|
|
devtype = NodeDevice.CAPABILITY_TYPE_PCI
|
2013-03-18 05:06:52 +08:00
|
|
|
addrstr, func = addrstr.split(".", 1)
|
|
|
|
addrstr, slot = addrstr.rsplit(":", 1)
|
|
|
|
domain = "0"
|
|
|
|
if addrstr.count(":"):
|
|
|
|
domain, bus = addrstr.split(":", 1)
|
|
|
|
else:
|
|
|
|
bus = addrstr
|
|
|
|
|
|
|
|
func = int(func, 16)
|
|
|
|
slot = int(slot, 16)
|
|
|
|
domain = int(domain, 16)
|
|
|
|
bus = int(bus, 16)
|
|
|
|
|
|
|
|
def pci_cmp(nodedev):
|
|
|
|
return ((int(nodedev.domain) == domain) and
|
|
|
|
(int(nodedev.function) == func) and
|
|
|
|
(int(nodedev.bus) == bus) and
|
|
|
|
(int(nodedev.slot) == slot))
|
|
|
|
cmp_func = pci_cmp
|
2013-09-23 06:13:24 +08:00
|
|
|
addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_PCI
|
2013-03-18 05:06:52 +08:00
|
|
|
|
|
|
|
elif addrstr.count(":"):
|
2013-09-23 06:13:24 +08:00
|
|
|
devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
|
2013-03-18 05:06:52 +08:00
|
|
|
vendor, product = addrstr.split(":")
|
|
|
|
vendor = int(vendor, 16)
|
|
|
|
product = int(product, 16)
|
|
|
|
|
|
|
|
def usbprod_cmp(nodedev):
|
|
|
|
return ((int(nodedev.vendor_id, 16) == vendor) and
|
|
|
|
(int(nodedev.product_id, 16) == product))
|
|
|
|
cmp_func = usbprod_cmp
|
2013-09-23 06:13:24 +08:00
|
|
|
addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_VENPRO
|
2013-03-18 05:06:52 +08:00
|
|
|
|
|
|
|
elif addrstr.count("."):
|
2013-09-23 06:13:24 +08:00
|
|
|
devtype = NodeDevice.CAPABILITY_TYPE_USBDEV
|
2013-03-18 05:06:52 +08:00
|
|
|
bus, addr = addrstr.split(".", 1)
|
|
|
|
bus = int(bus)
|
|
|
|
addr = int(addr)
|
|
|
|
|
|
|
|
def usbaddr_cmp(nodedev):
|
|
|
|
return ((int(nodedev.bus) == bus) and
|
|
|
|
(int(nodedev.device) == addr))
|
|
|
|
cmp_func = usbaddr_cmp
|
2013-09-23 06:13:24 +08:00
|
|
|
addr_type = NodeDevice.HOSTDEV_ADDR_TYPE_USB_BUSADDR
|
2013-09-28 06:06:39 +08:00
|
|
|
else:
|
2014-03-22 23:21:19 +08:00
|
|
|
raise RuntimeError("Unknown address type")
|
2013-03-18 05:06:52 +08:00
|
|
|
except:
|
2014-09-20 23:30:24 +08:00
|
|
|
logging.debug("Error parsing node device string.", exc_info=True)
|
2014-03-22 23:21:19 +08:00
|
|
|
raise
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-30 22:53:11 +08:00
|
|
|
return cmp_func, devtype, addr_type
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2014-09-20 23:30:24 +08:00
|
|
|
def _AddressStringToNodedev(conn, addrstr):
|
|
|
|
cmp_func, devtype, addr_type = _isAddressString(addrstr)
|
2013-03-18 05:06:52 +08:00
|
|
|
|
|
|
|
# Iterate over node devices and compare
|
2013-04-24 18:05:08 +08:00
|
|
|
count = 0
|
|
|
|
nodedev = None
|
|
|
|
|
2014-09-20 23:30:24 +08:00
|
|
|
for xmlobj in conn.fetch_all_nodedevs():
|
|
|
|
if xmlobj.device_type != devtype:
|
|
|
|
continue
|
|
|
|
if cmp_func(xmlobj):
|
|
|
|
nodedev = xmlobj
|
2013-04-24 18:05:08 +08:00
|
|
|
count += 1
|
|
|
|
|
|
|
|
if count == 1:
|
2013-09-28 06:06:39 +08:00
|
|
|
nodedev.addr_type = addr_type
|
|
|
|
return nodedev
|
2013-04-24 18:05:08 +08:00
|
|
|
elif count > 1:
|
|
|
|
raise ValueError(_("%s corresponds to multiple node devices") %
|
|
|
|
addrstr)
|
|
|
|
elif count < 1:
|
|
|
|
raise ValueError(_("Did not find a matching node device for '%s'") %
|
|
|
|
addrstr)
|
2013-03-18 05:06:52 +08:00
|
|
|
|
2013-04-14 02:34:52 +08:00
|
|
|
|
2013-03-18 05:06:52 +08:00
|
|
|
def _typeToDeviceClass(t):
|
2013-09-23 06:13:24 +08:00
|
|
|
if t == NodeDevice.CAPABILITY_TYPE_SYSTEM:
|
2013-03-18 05:06:52 +08:00
|
|
|
return SystemDevice
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_NET:
|
2013-03-18 05:06:52 +08:00
|
|
|
return NetDevice
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_PCI:
|
2013-03-18 05:06:52 +08:00
|
|
|
return PCIDevice
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_USBDEV:
|
2013-03-18 05:06:52 +08:00
|
|
|
return USBDevice
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_USBBUS:
|
2013-03-18 05:06:52 +08:00
|
|
|
return USBBus
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_STORAGE:
|
2013-03-18 05:06:52 +08:00
|
|
|
return StorageDevice
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_SCSIBUS:
|
2013-03-18 05:06:52 +08:00
|
|
|
return SCSIBus
|
2013-09-23 06:13:24 +08:00
|
|
|
elif t == NodeDevice.CAPABILITY_TYPE_SCSIDEV:
|
2013-03-18 05:06:52 +08:00
|
|
|
return SCSIDevice
|
|
|
|
else:
|
|
|
|
return NodeDevice
|