connection: Handle nodedev polling too
And cleanup up a bunch of nodedev functions as a result
This commit is contained in:
parent
8cd4958a19
commit
dd67c48233
|
@ -79,11 +79,15 @@ def openconn(uri):
|
|||
_conn_cache[uri]["vms"] = conn._fetch_all_guests_cached()
|
||||
_conn_cache[uri]["pools"] = conn._fetch_all_pools_cached()
|
||||
_conn_cache[uri]["vols"] = conn._fetch_all_vols_cached()
|
||||
_conn_cache[uri]["nodedevs"] = conn._fetch_all_nodedevs_cached()
|
||||
cache = _conn_cache[uri].copy()
|
||||
|
||||
def cb_fetch_all_guests():
|
||||
return cache["vms"]
|
||||
|
||||
def cb_fetch_all_nodedevs():
|
||||
return cache["nodedevs"]
|
||||
|
||||
def cb_fetch_all_pools():
|
||||
if "pools" not in cache:
|
||||
cache["pools"] = conn._fetch_all_pools_cached()
|
||||
|
@ -102,6 +106,7 @@ def openconn(uri):
|
|||
conn.cb_fetch_all_guests = cb_fetch_all_guests
|
||||
conn.cb_fetch_all_pools = cb_fetch_all_pools
|
||||
conn.cb_fetch_all_vols = cb_fetch_all_vols
|
||||
conn.cb_fetch_all_nodedevs = cb_fetch_all_nodedevs
|
||||
conn.cb_clear_cache = cb_clear_cache
|
||||
|
||||
return conn
|
||||
|
|
|
@ -164,6 +164,9 @@ class vmmConnection(vmmGObject):
|
|||
self._backend.cb_fetch_all_pools = (
|
||||
lambda: [obj.get_xmlobj(refresh_if_nec=False)
|
||||
for obj in self._pools.values()])
|
||||
self._backend.cb_fetch_all_nodedevs = (
|
||||
lambda: [obj.get_xmlobj(refresh_if_nec=False)
|
||||
for obj in self._nodedevs.values()])
|
||||
|
||||
def fetch_all_vols():
|
||||
ret = []
|
||||
|
|
|
@ -2057,7 +2057,7 @@ class ParserHostdev(VirtCLIParser):
|
|||
def set_name_cb(opts, inst, cliname, val):
|
||||
ignore = opts
|
||||
ignore = cliname
|
||||
val = NodeDevice.lookupNodeName(inst.conn, val)
|
||||
val = NodeDevice.lookupNodedevFromString(inst.conn, val)
|
||||
inst.set_from_nodedev(val)
|
||||
|
||||
self.set_param(None, "name", setter_cb=set_name_cb)
|
||||
|
|
|
@ -28,6 +28,7 @@ from . import util
|
|||
from . import capabilities as CapabilitiesParser
|
||||
from .cli import VirtOptionString
|
||||
from .guest import Guest
|
||||
from .nodedev import NodeDevice
|
||||
from .storage import StoragePool, StorageVolume
|
||||
|
||||
_virtinst_uri_magic = "__virtinst_test__"
|
||||
|
@ -96,6 +97,7 @@ class VirtualConnection(object):
|
|||
self.cb_fetch_all_guests = None
|
||||
self.cb_fetch_all_pools = None
|
||||
self.cb_fetch_all_vols = None
|
||||
self.cb_fetch_all_nodedevs = None
|
||||
self.cb_clear_cache = None
|
||||
|
||||
|
||||
|
@ -162,9 +164,27 @@ class VirtualConnection(object):
|
|||
self._uri = self._libvirtconn.getURI()
|
||||
self._urisplits = util.uri_split(self._uri)
|
||||
|
||||
def set_keep_alive(self, interval, count):
|
||||
if hasattr(self._libvirtconn, "setKeepAlive"):
|
||||
self._libvirtconn.setKeepAlive(interval, count)
|
||||
|
||||
|
||||
####################
|
||||
# Polling routines #
|
||||
####################
|
||||
|
||||
_FETCH_KEY_GUESTS = "vms"
|
||||
_FETCH_KEY_POOLS = "pools"
|
||||
_FETCH_KEY_VOLS = "vols"
|
||||
_FETCH_KEY_NODEDEVS = "nodedevs"
|
||||
|
||||
def clear_cache(self, pools=False):
|
||||
if self.cb_clear_cache:
|
||||
self.cb_clear_cache(pools=pools) # pylint: disable=not-callable
|
||||
return
|
||||
|
||||
if pools:
|
||||
self._fetch_cache.pop(self._FETCH_KEY_POOLS, None)
|
||||
|
||||
def _fetch_all_guests_cached(self):
|
||||
key = self._FETCH_KEY_GUESTS
|
||||
|
@ -200,10 +220,6 @@ class VirtualConnection(object):
|
|||
self._fetch_cache[key] = ret
|
||||
return ret
|
||||
|
||||
def set_keep_alive(self, interval, count):
|
||||
if hasattr(self._libvirtconn, "setKeepAlive"):
|
||||
self._libvirtconn.setKeepAlive(interval, count)
|
||||
|
||||
def fetch_all_pools(self):
|
||||
"""
|
||||
Returns a list of StoragePool objects
|
||||
|
@ -242,13 +258,26 @@ class VirtualConnection(object):
|
|||
return self.cb_fetch_all_vols() # pylint: disable=not-callable
|
||||
return self._fetch_all_vols_cached()
|
||||
|
||||
def clear_cache(self, pools=False):
|
||||
if self.cb_clear_cache:
|
||||
self.cb_clear_cache(pools=pools) # pylint: disable=not-callable
|
||||
return
|
||||
def _fetch_all_nodedevs_cached(self):
|
||||
key = self._FETCH_KEY_NODEDEVS
|
||||
if key in self._fetch_cache:
|
||||
return self._fetch_cache[key]
|
||||
|
||||
if pools:
|
||||
self._fetch_cache.pop(self._FETCH_KEY_POOLS, None)
|
||||
ignore, ignore, ret = pollhelpers.fetch_nodedevs(
|
||||
self, {}, lambda obj, ignore: obj)
|
||||
ret = [NodeDevice.parse(weakref.ref(self), obj.XMLDesc(0))
|
||||
for obj in ret.values()]
|
||||
if self.cache_object_fetch:
|
||||
self._fetch_cache[key] = ret
|
||||
return ret
|
||||
|
||||
def fetch_all_nodedevs(self):
|
||||
"""
|
||||
Returns a list of NodeDevice() objects
|
||||
"""
|
||||
if self.cb_fetch_all_nodedevs:
|
||||
return self.cb_fetch_all_nodedevs() # pylint: disable=not-callable
|
||||
return self._fetch_all_nodedevs_cached()
|
||||
|
||||
|
||||
#########################
|
||||
|
|
|
@ -53,8 +53,13 @@ class VirtualHostDevice(VirtualDevice):
|
|||
self.device = nodedev.device
|
||||
|
||||
elif nodedev.device_type == nodedev.CAPABILITY_TYPE_NET:
|
||||
parentnode = nodedev.lookupNodeName(self.conn, nodedev.parent)
|
||||
self.set_from_nodedev(parentnode, use_full_usb=use_full_usb)
|
||||
founddev = None
|
||||
for checkdev in self.conn.fetch_all_nodedevs():
|
||||
if checkdev.name == nodedev.parent:
|
||||
founddev = checkdev
|
||||
break
|
||||
|
||||
self.set_from_nodedev(founddev, use_full_usb=use_full_usb)
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown node device type %s" % nodedev)
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
import logging
|
||||
|
||||
import libvirt
|
||||
|
||||
from .xmlbuilder import XMLBuilder
|
||||
from .xmlbuilder import XMLProperty as _XMLProperty
|
||||
|
||||
|
@ -29,18 +27,6 @@ class XMLProperty(_XMLProperty):
|
|||
_track = False
|
||||
|
||||
|
||||
def _lookupNodeName(conn, name):
|
||||
try:
|
||||
nodedev = conn.nodeDeviceLookupByName(name)
|
||||
except libvirt.libvirtError, e:
|
||||
raise libvirt.libvirtError(
|
||||
_("Did not find node device '%s': %s" %
|
||||
(name, str(e))))
|
||||
|
||||
xml = nodedev.XMLDesc(0)
|
||||
return NodeDevice.parse(conn, xml)
|
||||
|
||||
|
||||
def _intify(val, do_hex=False):
|
||||
try:
|
||||
if do_hex:
|
||||
|
@ -73,7 +59,7 @@ class NodeDevice(XMLBuilder):
|
|||
HOSTDEV_ADDR_TYPE_USB_VENPRO) = range(1, 5)
|
||||
|
||||
@staticmethod
|
||||
def lookupNodeName(conn, name):
|
||||
def lookupNodedevFromString(conn, idstring):
|
||||
"""
|
||||
Convert the passed libvirt node device name to a NodeDevice
|
||||
instance, with proper error reporting. If the name is name is not
|
||||
|
@ -81,8 +67,11 @@ class NodeDevice(XMLBuilder):
|
|||
devAddressToNodeDev
|
||||
|
||||
@param conn: libvirt.virConnect instance to perform the lookup on
|
||||
@param name: libvirt node device name to lookup, or address for
|
||||
_devAddressToNodedev
|
||||
@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)
|
||||
|
||||
@rtype: L{NodeDevice} instance
|
||||
"""
|
||||
|
@ -90,15 +79,19 @@ class NodeDevice(XMLBuilder):
|
|||
raise ValueError(_("Connection does not support host device "
|
||||
"enumeration."))
|
||||
|
||||
try:
|
||||
return _lookupNodeName(conn, name)
|
||||
except libvirt.libvirtError, e:
|
||||
try:
|
||||
_isAddressStr(name)
|
||||
except:
|
||||
raise e
|
||||
# First try and see if this is a libvirt nodedev name
|
||||
for nodedev in conn.fetch_all_nodedevs():
|
||||
if nodedev.name == idstring:
|
||||
return nodedev
|
||||
|
||||
try:
|
||||
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))
|
||||
|
||||
return _devAddressToNodedev(conn, name)
|
||||
|
||||
@staticmethod
|
||||
def parse(conn, xml):
|
||||
|
@ -346,7 +339,7 @@ class SCSIBus(NodeDevice):
|
|||
wwpn = XMLProperty("./capability/capability[@type='fc_host']/wwpn")
|
||||
|
||||
|
||||
def _isAddressStr(addrstr):
|
||||
def _isAddressString(addrstr):
|
||||
cmp_func = None
|
||||
addr_type = None
|
||||
|
||||
|
@ -401,40 +394,24 @@ def _isAddressStr(addrstr):
|
|||
else:
|
||||
raise RuntimeError("Unknown address type")
|
||||
except:
|
||||
logging.exception("Error parsing node device string.")
|
||||
logging.debug("Error parsing node device string.", exc_info=True)
|
||||
raise
|
||||
|
||||
return cmp_func, devtype, addr_type
|
||||
|
||||
|
||||
def _devAddressToNodedev(conn, addrstr):
|
||||
"""
|
||||
Look up the passed host device address string as a libvirt node device,
|
||||
parse its xml, and return a NodeDevice instance.
|
||||
|
||||
@param conn: libvirt.virConnect instance to perform the lookup on
|
||||
@param addrstr: host device string to parse and lookup
|
||||
- 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)
|
||||
@param addrstr: C{str}
|
||||
"""
|
||||
try:
|
||||
ret = _isAddressStr(addrstr)
|
||||
except:
|
||||
raise ValueError(_("Could not determine format of '%s'") % addrstr)
|
||||
|
||||
cmp_func, devtype, addr_type = ret
|
||||
def _AddressStringToNodedev(conn, addrstr):
|
||||
cmp_func, devtype, addr_type = _isAddressString(addrstr)
|
||||
|
||||
# Iterate over node devices and compare
|
||||
count = 0
|
||||
nodedev = None
|
||||
|
||||
nodenames = conn.listDevices(devtype, 0)
|
||||
for name in nodenames:
|
||||
tmpnode = _lookupNodeName(conn, name)
|
||||
if cmp_func(tmpnode):
|
||||
nodedev = tmpnode
|
||||
for xmlobj in conn.fetch_all_nodedevs():
|
||||
if xmlobj.device_type != devtype:
|
||||
continue
|
||||
if cmp_func(xmlobj):
|
||||
nodedev = xmlobj
|
||||
count += 1
|
||||
|
||||
if count == 1:
|
||||
|
|
Loading…
Reference in New Issue