qubes: Cache QubesHost requests, fix xen-specific members

Acknowledgement:
This commit is a result of core3 review by Marek.
This commit is contained in:
Wojtek Porczyk 2015-01-08 19:13:51 +01:00
parent 2a62780ea2
commit c2a35c02b4

View File

@ -44,6 +44,7 @@ else:
import libvirt import libvirt
try: try:
import xen.lowlevel.xs import xen.lowlevel.xs
import xen.lowlevel.xc
except ImportError: except ImportError:
pass pass
@ -94,6 +95,8 @@ class VMMConnection(object):
if 'xen.lowlevel.xs' in sys.modules: if 'xen.lowlevel.xs' in sys.modules:
self._xs = xen.lowlevel.xs.xs() self._xs = xen.lowlevel.xs.xs()
if 'xen.lowlevel.cs' in sys.modules:
self._xc = xen.lowlevel.xc.xc()
self._libvirt_conn = libvirt.open(defaults['libvirt_uri']) self._libvirt_conn = libvirt.open(defaults['libvirt_uri'])
if self._libvirt_conn == None: if self._libvirt_conn == None:
raise QubesException("Failed connect to libvirt driver") raise QubesException("Failed connect to libvirt driver")
@ -110,10 +113,26 @@ class VMMConnection(object):
def xs(self): def xs(self):
'''Connection to Xen Store '''Connection to Xen Store
This property in available only when running on Xen.''' This property in available only when running on Xen.
'''
# XXX what about the case when we run under KVM, but xen modules are importable?
if 'xen.lowlevel.xs' not in sys.modules: if 'xen.lowlevel.xs' not in sys.modules:
return None raise AttributeError('xs object is available under Xen hypervisor only')
self.init_vmm_connection()
return self._xs
@__builtin__.property
def xc(self):
'''Connection to Xen
This property in available only when running on Xen.
'''
# XXX what about the case when we run under KVM, but xen modules are importable?
if 'xen.lowlevel.xc' not in sys.modules:
raise AttributeError('xc object is available under Xen hypervisor only')
self.init_vmm_connection() self.init_vmm_connection()
return self._xs return self._xs
@ -122,44 +141,79 @@ class VMMConnection(object):
class QubesHost(object): class QubesHost(object):
'''Basic information about host machine '''Basic information about host machine
:param Qubes app: Qubes application context (must have :py:attr:`Qubes.vmm` attribute defined) :param qubes.Qubes app: Qubes application context (must have :py:attr:`Qubes.vmm` attribute defined)
''' '''
def __init__(self, app): def __init__(self, app):
self._app = app self._app = app
self._no_cpus = None
def _fetch(self):
if self._no_cpus is not None:
return
(model, memory, cpus, mhz, nodes, socket, cores, threads) = \ (model, memory, cpus, mhz, nodes, socket, cores, threads) = \
self._app.vmm.libvirt_conn.getInfo() self._app.vmm.libvirt_conn.getInfo()
self._total_mem = long(memory)*1024 self._total_mem = long(memory)*1024
self._no_cpus = cpus self._no_cpus = cpus
# print "QubesHost: total_mem = {0}B".format (self.xen_total_mem) self.app.log.debug('QubesHost: no_cpus={} memory_total={}'.format(self.no_cpus, self.memory_total))
# print "QubesHost: free_mem = {0}".format (self.get_free_xen_memory()) try:
# print "QubesHost: total_cpus = {0}".format (self.xen_no_cpus) self.app.log.debug('QubesHost: xen_free_memory={}'.format(self.get_free_xen_memory()))
except NotImplementedError:
pass
@__builtin__.property @__builtin__.property
def memory_total(self): def memory_total(self):
'''Total memory, in bytes''' '''Total memory, in bytes'''
self._fetch()
return self._total_mem return self._total_mem
@__builtin__.property @__builtin__.property
def no_cpus(self): def no_cpus(self):
'''Noumber of CPUs''' '''Number of CPUs'''
self._fetch()
return self._no_cpus return self._no_cpus
# TODO
def get_free_xen_memory(self):
ret = self.physinfo['free_memory']
return long(ret)
# TODO def get_free_xen_memory(self):
def measure_cpu_usage(self, previous=None, previous_time = None, '''Get free memory from Xen's physinfo.
:raises NotImplementedError: when not under Xen
'''
try:
self._physinfo = self.app.xc.physinfo()
except AttributeError:
raise NotImplementedError('This function requires Xen hypervisor')
return long(self._physinfo['free_memory'])
def measure_cpu_usage(self, previous_time=None, previous=None,
wait_time=1): wait_time=1):
"""measure cpu usage for all domains at once""" '''Measure cpu usage for all domains at once.
This function requires Xen hypervisor.
.. versionchanged:: 3.0
argument order to match return tuple
:raises NotImplementedError: when not under Xen
'''
if previous is None: if previous is None:
previous_time = time.time() previous_time = time.time()
previous = {} previous = {}
info = self._app.vmm.xc.domain_getinfo(0, qubes_max_qid) try:
info = self._app.vmm.xc.domain_getinfo(0, qubes_max_qid)
except AttributeError:
raise NotImplementedError(
'This function requires Xen hypervisor')
for vm in info: for vm in info:
previous[vm['domid']] = {} previous[vm['domid']] = {}
previous[vm['domid']]['cpu_time'] = ( previous[vm['domid']]['cpu_time'] = (
@ -169,7 +223,11 @@ class QubesHost(object):
current_time = time.time() current_time = time.time()
current = {} current = {}
info = self._app.vmm.xc.domain_getinfo(0, qubes_max_qid) try:
info = self._app.vmm.xc.domain_getinfo(0, qubes_max_qid)
except AttributeError:
raise NotImplementedError(
'This function requires Xen hypervisor')
for vm in info: for vm in info:
current[vm['domid']] = {} current[vm['domid']] = {}
current[vm['domid']]['cpu_time'] = ( current[vm['domid']]['cpu_time'] = (