mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-12-23 17:34:21 +03:00
virtManager: connection: Switch to tick() paradigm for all objects
This is going to be much slower than what we currently do, but we will be trying to fix that shortly.
This commit is contained in:
parent
2e47d2e5fa
commit
b7ee86541d
@ -405,6 +405,8 @@ class vmmConnection(vmmGObject):
|
||||
return self._backend.check_interface_support(*args)
|
||||
def check_stream_support(self, *args):
|
||||
return self._backend.check_stream_support(*args)
|
||||
def check_net_support(self, *args):
|
||||
return self._backend.check_net_support(*args)
|
||||
|
||||
def is_storage_capable(self):
|
||||
if self._storage_capable is None:
|
||||
@ -969,7 +971,7 @@ class vmmConnection(vmmGObject):
|
||||
except Exception, e:
|
||||
logging.debug("Unable to list inactive %ss: %s", typename, e)
|
||||
|
||||
def check_obj(key, is_active):
|
||||
def check_obj(key):
|
||||
if key not in origlist:
|
||||
try:
|
||||
obj = lookup_func(key)
|
||||
@ -979,30 +981,18 @@ class vmmConnection(vmmGObject):
|
||||
return
|
||||
|
||||
# Object is brand new this tick period
|
||||
current[key] = build_func(obj, key, is_active)
|
||||
current[key] = build_func(obj, key)
|
||||
new[key] = current[key]
|
||||
else:
|
||||
# Previously known object, see if it changed state
|
||||
current[key] = origlist[key]
|
||||
|
||||
if current[key].is_active() != is_active:
|
||||
current[key].set_active(is_active)
|
||||
|
||||
del origlist[key]
|
||||
|
||||
for name in newActiveNames:
|
||||
for name in newActiveNames + newInactiveNames:
|
||||
try:
|
||||
check_obj(name, True)
|
||||
check_obj(name)
|
||||
except:
|
||||
logging.exception("Couldn't fetch active "
|
||||
"%s '%s'", typename, name)
|
||||
|
||||
for name in newInactiveNames:
|
||||
try:
|
||||
check_obj(name, False)
|
||||
except:
|
||||
logging.exception("Couldn't fetch inactive "
|
||||
"%s '%s'", typename, name)
|
||||
logging.exception("Couldn't fetch %s '%s'", typename, name)
|
||||
|
||||
return (origlist, new, current)
|
||||
|
||||
@ -1013,8 +1003,7 @@ class vmmConnection(vmmGObject):
|
||||
inactive_list = self._backend.listDefinedNetworks
|
||||
check_support = self.is_network_capable
|
||||
lookup_func = self._backend.networkLookupByName
|
||||
build_func = (lambda obj, key, is_active:
|
||||
vmmNetwork(self, obj, key, is_active))
|
||||
build_func = (lambda obj, key: vmmNetwork(self, obj, key))
|
||||
|
||||
return self._poll_helper(orig, name, check_support,
|
||||
active_list, inactive_list,
|
||||
@ -1027,8 +1016,7 @@ class vmmConnection(vmmGObject):
|
||||
inactive_list = self._backend.listDefinedStoragePools
|
||||
check_support = self.is_storage_capable
|
||||
lookup_func = self._backend.storagePoolLookupByName
|
||||
build_func = (lambda obj, key, is_active:
|
||||
vmmStoragePool(self, obj, key, is_active))
|
||||
build_func = (lambda obj, key: vmmStoragePool(self, obj, key))
|
||||
|
||||
return self._poll_helper(orig, name, check_support,
|
||||
active_list, inactive_list,
|
||||
@ -1041,8 +1029,7 @@ class vmmConnection(vmmGObject):
|
||||
inactive_list = self._backend.listDefinedInterfaces
|
||||
check_support = self.is_interface_capable
|
||||
lookup_func = self._backend.interfaceLookupByName
|
||||
build_func = (lambda obj, key, is_active:
|
||||
vmmInterface(self, obj, key, is_active))
|
||||
build_func = (lambda obj, key: vmmInterface(self, obj, key))
|
||||
|
||||
return self._poll_helper(orig, name, check_support,
|
||||
active_list, inactive_list,
|
||||
@ -1056,7 +1043,7 @@ class vmmConnection(vmmGObject):
|
||||
inactive_list = lambda: []
|
||||
check_support = self.is_nodedev_capable
|
||||
lookup_func = self._backend.nodeDeviceLookupByName
|
||||
build_func = lambda obj, key, ignore: vmmNodeDevice(self, obj, key)
|
||||
build_func = lambda obj, key: vmmNodeDevice(self, obj, key)
|
||||
|
||||
return self._poll_helper(orig, name, check_support,
|
||||
active_list, inactive_list,
|
||||
@ -1236,18 +1223,24 @@ class vmmConnection(vmmGObject):
|
||||
|
||||
self.idle_add(tick_send_signals)
|
||||
|
||||
# Finally, we sample each domain
|
||||
now = time.time()
|
||||
|
||||
updateVMs = vms.values()
|
||||
if noStatsUpdate:
|
||||
updateVMs = newVMs.values()
|
||||
ticklist = []
|
||||
def add_to_ticklist(l, args=()):
|
||||
ticklist.extend([(o, args) for o in l.values()])
|
||||
|
||||
for vm in updateVMs:
|
||||
updateVMs = noStatsUpdate and newVMs or vms
|
||||
add_to_ticklist(updateVMs, (now,))
|
||||
add_to_ticklist(noStatsUpdate and newNets or nets)
|
||||
add_to_ticklist(noStatsUpdate and newPools or pools)
|
||||
add_to_ticklist(noStatsUpdate and newInterfaces or interfaces)
|
||||
add_to_ticklist(self.mediadevs)
|
||||
|
||||
for obj, args in ticklist:
|
||||
try:
|
||||
vm.tick(now)
|
||||
obj.tick(*args)
|
||||
except Exception, e:
|
||||
logging.exception("Tick for VM '%s' failed", vm.get_name())
|
||||
logging.exception("Tick for %s failed", obj)
|
||||
if (isinstance(e, libvirt.libvirtError) and
|
||||
(getattr(e, "get_error_code")() ==
|
||||
libvirt.VIR_ERR_SYSTEM_ERROR)):
|
||||
@ -1257,11 +1250,8 @@ class vmmConnection(vmmGObject):
|
||||
"connection doesn't seem to have dropped. "
|
||||
"Ignoring.")
|
||||
|
||||
for dev in self.mediadevs.values():
|
||||
dev.tick()
|
||||
|
||||
if not noStatsUpdate:
|
||||
self._recalculate_stats(now, updateVMs)
|
||||
self._recalculate_stats(now, updateVMs.values())
|
||||
self.idle_emit("resources-sampled")
|
||||
|
||||
return 1
|
||||
|
@ -1714,9 +1714,6 @@ class vmmDomain(vmmLibvirtObject):
|
||||
return rd, wr
|
||||
|
||||
def tick(self, now=None):
|
||||
if self.conn.get_state() != self.conn.STATE_ACTIVE:
|
||||
return
|
||||
|
||||
if now is None:
|
||||
now = time.time()
|
||||
|
||||
|
@ -25,12 +25,12 @@ from virtManager.libvirtobject import vmmLibvirtObject
|
||||
|
||||
|
||||
class vmmInterface(vmmLibvirtObject):
|
||||
def __init__(self, conn, interface, name, active):
|
||||
def __init__(self, conn, interface, name):
|
||||
vmmLibvirtObject.__init__(self, conn)
|
||||
|
||||
self.interface = interface # Libvirt virInterface object
|
||||
self.name = name # String name
|
||||
self.active = active # bool indicating if it is running
|
||||
self.active = True # bool indicating if it is running
|
||||
|
||||
self._xml = None # xml cache
|
||||
self._xml_flags = None
|
||||
@ -39,6 +39,9 @@ class vmmInterface(vmmLibvirtObject):
|
||||
self._active_xml_flags) = self.conn.get_interface_flags(
|
||||
self.interface)
|
||||
|
||||
self._support_isactive = None
|
||||
|
||||
self.tick()
|
||||
self.refresh_xml()
|
||||
|
||||
# Routines from vmmLibvirtObject
|
||||
@ -60,11 +63,27 @@ class vmmInterface(vmmLibvirtObject):
|
||||
return util.xpath(self.get_xml(inactive=True), *args, **kwargs)
|
||||
|
||||
def set_active(self, state):
|
||||
if state != self.active:
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
if state == self.active:
|
||||
return
|
||||
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
self.active = state
|
||||
self.refresh_xml()
|
||||
|
||||
def _backend_get_active(self):
|
||||
ret = True
|
||||
if self._support_isactive is None:
|
||||
self._support_isactive = self.conn.check_interface_support(
|
||||
self.interface,
|
||||
self.conn.SUPPORT_INTERFACE_ISACTIVE)
|
||||
|
||||
if not self._support_isactive:
|
||||
return True
|
||||
return bool(self.interface.isActive())
|
||||
|
||||
def tick(self):
|
||||
self.set_active(self._backend_get_active())
|
||||
|
||||
def is_active(self):
|
||||
return self.active
|
||||
|
||||
|
@ -82,6 +82,7 @@ class vmmLibvirtObject(vmmGObject):
|
||||
def tick(self, now):
|
||||
ignore = now
|
||||
|
||||
|
||||
##################
|
||||
# Public XML API #
|
||||
##################
|
||||
@ -120,6 +121,7 @@ class vmmLibvirtObject(vmmGObject):
|
||||
if origxml != self._xml or forcesignal:
|
||||
self.idle_emit("config-changed")
|
||||
|
||||
|
||||
######################################
|
||||
# Internal XML cache/update routines #
|
||||
######################################
|
||||
@ -128,6 +130,7 @@ class vmmLibvirtObject(vmmGObject):
|
||||
# Mark cached xml as invalid
|
||||
self._is_xml_valid = False
|
||||
|
||||
|
||||
##########################
|
||||
# Internal API functions #
|
||||
##########################
|
||||
|
@ -47,11 +47,16 @@ class vmmNetwork(vmmLibvirtObject):
|
||||
|
||||
return desc
|
||||
|
||||
def __init__(self, conn, net, uuid, active):
|
||||
def __init__(self, conn, net, uuid):
|
||||
vmmLibvirtObject.__init__(self, conn)
|
||||
self.net = net
|
||||
self.uuid = uuid
|
||||
self.active = active
|
||||
self.active = True
|
||||
|
||||
self._support_isactive = None
|
||||
|
||||
self.tick()
|
||||
|
||||
|
||||
# Required class methods
|
||||
def get_name(self):
|
||||
@ -62,8 +67,9 @@ class vmmNetwork(vmmLibvirtObject):
|
||||
return self.conn.get_backend().networkDefineXML(xml)
|
||||
|
||||
def set_active(self, state):
|
||||
if state != self.active:
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
if state == self.active:
|
||||
return
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
self.active = state
|
||||
|
||||
def is_active(self):
|
||||
@ -89,7 +95,6 @@ class vmmNetwork(vmmLibvirtObject):
|
||||
|
||||
def delete(self):
|
||||
self.net.undefine()
|
||||
del(self.net)
|
||||
self.net = None
|
||||
|
||||
def set_autostart(self, value):
|
||||
@ -98,6 +103,24 @@ class vmmNetwork(vmmLibvirtObject):
|
||||
def get_autostart(self):
|
||||
return self.net.autostart()
|
||||
|
||||
def _backend_get_active(self):
|
||||
if self._support_isactive is None:
|
||||
self._support_isactive = self.conn.check_net_support(
|
||||
self.net,
|
||||
self.conn.SUPPORT_NET_ISACTIVE)
|
||||
|
||||
if not self._support_isactive:
|
||||
return True
|
||||
return bool(self.net.isActive())
|
||||
|
||||
def tick(self):
|
||||
self.set_active(self._backend_get_active())
|
||||
|
||||
|
||||
########################
|
||||
# XML parsing routines #
|
||||
########################
|
||||
|
||||
def get_ipv4_static_route(self):
|
||||
doc = None
|
||||
ret = None
|
||||
|
@ -34,16 +34,19 @@ class vmmStoragePool(vmmLibvirtObject):
|
||||
"refreshed": (GObject.SignalFlags.RUN_FIRST, None, [])
|
||||
}
|
||||
|
||||
def __init__(self, conn, pool, uuid, active):
|
||||
def __init__(self, conn, pool, uuid):
|
||||
vmmLibvirtObject.__init__(self, conn)
|
||||
|
||||
self.pool = pool # Libvirt pool object
|
||||
self.uuid = uuid # String UUID
|
||||
self.active = active # bool indicating if it is running
|
||||
self.active = True # bool indicating if it is running
|
||||
|
||||
self._volumes = {} # UUID->vmmStorageVolume mapping of the
|
||||
# pools associated volumes
|
||||
|
||||
self._support_isactive = None
|
||||
|
||||
self.tick()
|
||||
self.refresh()
|
||||
|
||||
# Required class methods
|
||||
@ -56,8 +59,9 @@ class vmmStoragePool(vmmLibvirtObject):
|
||||
|
||||
|
||||
def set_active(self, state):
|
||||
if state != self.active:
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
if state == self.active:
|
||||
return
|
||||
self.idle_emit(state and "started" or "stopped")
|
||||
self.active = state
|
||||
self.refresh_xml()
|
||||
|
||||
@ -119,6 +123,19 @@ class vmmStoragePool(vmmLibvirtObject):
|
||||
def get_volume(self, uuid):
|
||||
return self._volumes[uuid]
|
||||
|
||||
def _backend_get_active(self):
|
||||
if self._support_isactive is None:
|
||||
self._support_isactive = self.conn.check_pool_support(
|
||||
self.pool,
|
||||
self.conn.SUPPORT_STORAGE_ISACTIVE)
|
||||
|
||||
if not self._support_isactive:
|
||||
return True
|
||||
return bool(self.pool.isActive())
|
||||
|
||||
def tick(self):
|
||||
self.set_active(self._backend_get_active())
|
||||
|
||||
def refresh(self):
|
||||
if not self.active:
|
||||
return
|
||||
|
@ -233,6 +233,8 @@ class VirtualConnection(object):
|
||||
def check_stream_support(self, feature):
|
||||
return (self.check_conn_support(self.SUPPORT_CONN_STREAM) and
|
||||
support.check_support(self, feature, self))
|
||||
def check_net_support(self, net, feature):
|
||||
return support.check_support(self, feature, net)
|
||||
|
||||
|
||||
###################
|
||||
|
@ -35,7 +35,7 @@ from virtinst import util
|
||||
SUPPORT_CONN_MAXVCPUS_XML,
|
||||
SUPPORT_CONN_STREAM,
|
||||
SUPPORT_CONN_GETVERSION,
|
||||
SUPPORT_CONN_LIBVERSION) = range(12)
|
||||
SUPPORT_CONN_LIBVERSION) = range(1, 13)
|
||||
|
||||
# Flags for check_domain_support
|
||||
(SUPPORT_DOMAIN_GETVCPUS,
|
||||
@ -51,13 +51,15 @@ from virtinst import util
|
||||
|
||||
# Flags for check_pool_support
|
||||
(SUPPORT_STORAGE_CREATEVOLFROM,
|
||||
SUPPORT_STORAGE_UPLOAD) = range(2000, 2002)
|
||||
SUPPORT_STORAGE_UPLOAD,
|
||||
SUPPORT_STORAGE_ISACTIVE) = range(2000, 2003)
|
||||
|
||||
# Flags for check_nodedev_support
|
||||
(SUPPORT_NODEDEV_PCI_DETACH,) = range(3000, 3001)
|
||||
|
||||
# Flags for check_interface_support
|
||||
(SUPPORT_INTERFACE_XML_INACTIVE,) = range(4000, 4001)
|
||||
(SUPPORT_INTERFACE_XML_INACTIVE,
|
||||
SUPPORT_INTERFACE_ISACTIVE) = range(4000, 4002)
|
||||
|
||||
# Flags for check_conn_hv_support
|
||||
(SUPPORT_CONN_HV_VIRTIO,
|
||||
@ -72,6 +74,9 @@ from virtinst import util
|
||||
# Flags for check_stream_support
|
||||
(SUPPORT_STREAM_UPLOAD,) = range(6000, 6001)
|
||||
|
||||
# Flags for check_net_support
|
||||
(SUPPORT_NET_ISACTIVE,) = range(7000, 7001)
|
||||
|
||||
|
||||
# Possible keys:
|
||||
#
|
||||
@ -230,6 +235,11 @@ _support_dict = {
|
||||
"function" : "virStoragePool.createXMLFrom",
|
||||
"version" : 6004,
|
||||
},
|
||||
SUPPORT_STORAGE_ISACTIVE : {
|
||||
"function" : "virStoragePool.isActive",
|
||||
"args": (),
|
||||
},
|
||||
|
||||
|
||||
##################
|
||||
# Nodedev checks #
|
||||
@ -251,6 +261,10 @@ _support_dict = {
|
||||
"args" : (),
|
||||
"flag" : "VIR_INTERFACE_XML_INACTIVE",
|
||||
},
|
||||
SUPPORT_INTERFACE_ISACTIVE : {
|
||||
"function" : "virInterface.isActive",
|
||||
"args": (),
|
||||
},
|
||||
|
||||
|
||||
##################
|
||||
@ -304,11 +318,25 @@ _support_dict = {
|
||||
},
|
||||
|
||||
|
||||
#################
|
||||
# Stream checks #
|
||||
#################
|
||||
|
||||
SUPPORT_STREAM_UPLOAD : {
|
||||
# Latest I tested with, and since we will use it by default
|
||||
# for URL installs, want to be sure it works
|
||||
"version" : 9004,
|
||||
},
|
||||
|
||||
|
||||
##################
|
||||
# Network checks #
|
||||
##################
|
||||
|
||||
SUPPORT_NET_ISACTIVE : {
|
||||
"function" : "virNetwork.isActive",
|
||||
"args": (),
|
||||
},
|
||||
}
|
||||
|
||||
# RHEL6 has lots of feature backports, and since libvirt doesn't
|
||||
|
Loading…
Reference in New Issue
Block a user