Use vcpu.x.time and vcpu.x.wait values in libvirt inspector
If possible, calculate cputime from vcpu time + vcpu wait.
Fall back to cpu.time, if any vcpu.x.time or vcpu.x.wait
values are missing.
derived from I7bce33854dfe9c7b0e03b8c22721d04028183701
Co-Authored-By: Michael Ly <msly@us.ibm.com>
Co-Authored-By: Avi Weit <WEIT@il.ibm.com>
Co-Authored-By: Jorge Rodriguez <jorgedr@us.ibm.com>
Co-Authored-By: Karolyn Chambers <Karolyn.Chambers@target.com>
Co-Authored-By: Daniel Berrange <berrange@redhat.com>
Co-Authored-By: gordon chung <gord@live.ca>
Change-Id: I20700a32d608b3444b22c5ae460002eeb86d78ae
Closes-bug: #1677159
Closes-bug: #1421584
(cherry picked from commit a4ec0911a3
)
This commit is contained in:
parent
09b8713a6d
commit
1f14b191e0
|
@ -75,10 +75,30 @@ class LibvirtInspector(virt_inspector.Inspector):
|
|||
domain = self._get_domain_not_shut_off_or_raise(instance)
|
||||
# TODO(gordc): this can probably be cached since it can be used to get
|
||||
# all data related
|
||||
stats = self.connection.domainListGetStats([domain])
|
||||
dom_stat = stats[0][1]
|
||||
return virt_inspector.CPUStats(number=dom_stat['vcpu.current'],
|
||||
time=dom_stat['cpu.time'])
|
||||
stats = self.connection.domainListGetStats([domain], 0)[0][1]
|
||||
cpu_time = 0
|
||||
current_cpus = stats.get('vcpu.current')
|
||||
# Iterate over the maximum number of CPUs here, and count the
|
||||
# actual number encountered, since the vcpu.x structure can
|
||||
# have holes according to
|
||||
# https://libvirt.org/git/?p=libvirt.git;a=blob;f=src/libvirt-domain.c
|
||||
# virConnectGetAllDomainStats()
|
||||
for vcpu in six.moves.range(stats.get('vcpu.maximum', 0)):
|
||||
try:
|
||||
cpu_time += (stats.get('vcpu.%s.time' % vcpu) +
|
||||
stats.get('vcpu.%s.wait' % vcpu))
|
||||
current_cpus -= 1
|
||||
except TypeError:
|
||||
# pass here, if there are too many holes, the cpu count will
|
||||
# not match, so don't need special error handling.
|
||||
pass
|
||||
|
||||
if current_cpus:
|
||||
# There wasn't enough data, so fall back
|
||||
cpu_time = stats.get('cpu.time')
|
||||
|
||||
return virt_inspector.CPUStats(number=stats['vcpu.current'],
|
||||
time=cpu_time)
|
||||
|
||||
def inspect_cpu_l3_cache(self, instance):
|
||||
domain = self._lookup_by_uuid(instance)
|
||||
|
|
|
@ -51,7 +51,30 @@ class TestLibvirtInspection(base.BaseTestCase):
|
|||
self.domain = mock.Mock()
|
||||
self.addCleanup(mock.patch.stopall)
|
||||
|
||||
def test_inspect_cpus(self):
|
||||
def test_inspect_cpus_stats(self):
|
||||
fake_stats = [({}, {'vcpu.current': 2,
|
||||
'vcpu.maximum': 4,
|
||||
'vcpu.0.time': 10000,
|
||||
'vcpu.2.time': 10000,
|
||||
'vcpu.0.wait': 10000,
|
||||
'vcpu.2.wait': 10000,
|
||||
'cpu.time': 999999})]
|
||||
|
||||
with contextlib.ExitStack() as stack:
|
||||
stack.enter_context(mock.patch.object(self.inspector.connection,
|
||||
'lookupByUUIDString',
|
||||
return_value=self.domain))
|
||||
stack.enter_context(mock.patch.object(self.domain, 'info',
|
||||
return_value=(0, 0, 0,
|
||||
None, None)))
|
||||
stack.enter_context(mock.patch.object(self.inspector.connection,
|
||||
'domainListGetStats',
|
||||
return_value=fake_stats))
|
||||
cpu_info = self.inspector.inspect_cpus(self.instance)
|
||||
self.assertEqual(2, cpu_info.number)
|
||||
self.assertEqual(40000, cpu_info.time)
|
||||
|
||||
def test_inspect_cpus_stats_fallback_cpu_time(self):
|
||||
fake_stats = [({}, {'cpu.time': 999999, 'vcpu.current': 2})]
|
||||
with contextlib.ExitStack() as stack:
|
||||
stack.enter_context(mock.patch.object(self.inspector.connection,
|
||||
|
|
Loading…
Reference in New Issue