From 97dc203690393940914039824204310fd3d57473 Mon Sep 17 00:00:00 2001
From: "Daniel P. Berrange" <berrange@redhat.com>
Date: Tue, 6 Aug 2013 15:46:02 +0100
Subject: [PATCH] Fix handling of flags in get_vcpu_info()
https://bugzilla.redhat.com/show_bug.cgi?id=994139
We must always use virDomainGetVcpus if flags is zero and
fall back to virDomainGetVcpuPinInfo if we get an error
indicating the guest was shutoff.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 08613905c70525810dfc107c54f3b9ddf7e4ae7c)
---
Virt.xs | 21 +++++++++++++++++----
examples/vcpuinfo.pl | 4 ++--
lib/Sys/Virt/Domain.pm | 6 ++++--
3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/Virt.xs b/Virt.xs
index f8ebce7..e6b431c 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -4370,12 +4370,21 @@ get_vcpu_info(dom, flags=0)
maplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
Newx(cpumaps, dominfo.nrVirtCpu * maplen, unsigned char);
- if (flags && (flags & VIR_DOMAIN_AFFECT_CONFIG)) {
- Newx(info, dominfo.nrVirtCpu, virVcpuInfo);
+ if (!flags) {
+ Newx(info, dominfo.nrVirtCpu, virVcpuInfo);
if ((nvCpus = virDomainGetVcpus(dom, info, dominfo.nrVirtCpu, cpumaps, maplen)) < 0) {
+ virErrorPtr err = virGetLastError();
Safefree(info);
- Safefree(cpumaps);
- _croak_error();
+ info = NULL;
+ if (err && err->code == VIR_ERR_OPERATION_INVALID) {
+ if ((nvCpus = virDomainGetVcpuPinInfo(dom, dominfo.nrVirtCpu, cpumaps, maplen, flags)) < 0) {
+ Safefree(cpumaps);
+ _croak_error();
+ }
+ } else {
+ Safefree(cpumaps);
+ _croak_error();
+ }
}
} else {
info = NULL;
@@ -4393,6 +4402,10 @@ get_vcpu_info(dom, flags=0)
(void)hv_store(rec, "state", 5, newSViv(info[i].state), 0);
(void)hv_store(rec, "cpuTime", 7, virt_newSVull(info[i].cpuTime), 0);
(void)hv_store(rec, "cpu", 3, newSViv(info[i].cpu), 0);
+ } else {
+ (void)hv_store(rec, "state", 5, newSViv(0), 0);
+ (void)hv_store(rec, "cpuTime", 7, virt_newSVull(0), 0);
+ (void)hv_store(rec, "cpu", 3, newSViv(0), 0);
}
(void)hv_store(rec, "affinity", 8, newSVpvn((char*)cpumaps + (i *maplen), maplen), 0);
PUSHs(newRV_noinc((SV *)rec));
diff --git a/examples/vcpuinfo.pl b/examples/vcpuinfo.pl
index 668a0aa..6b07433 100644
--- a/examples/vcpuinfo.pl
+++ b/examples/vcpuinfo.pl
@@ -9,12 +9,12 @@ my $con = Sys::Virt->new(address => $addr, readonly => 1);
print "VMM type: ", $con->get_type(), "\n";
-foreach my $dom (sort { $a->get_id <=> $b->get_id } $con->list_domains) {
+foreach my $dom (sort { $a->get_id <=> $b->get_id } $con->list_all_domains) {
print "Domain: {\n";
print " ID: ", $dom->get_id(), " '" , $dom->get_name(), "'\n";
print " UUID: ", $dom->get_uuid_string(), "\n";
my $nodeinfo = $con->get_node_info;
- my @info = $dom->get_vcpu_info;
+ my @info = $dom->get_vcpu_info(Sys::Virt::Domain::AFFECT_CONFIG);
foreach my $info (@info) {
print " VCPU: {\n";
diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm
index 3207d0b..dc5b9cf 100644
--- a/lib/Sys/Virt/Domain.pm
+++ b/lib/Sys/Virt/Domain.pm
@@ -1113,7 +1113,7 @@ or multi-card configuration. C<$st> must be a C<Sys::Virt::Stream>
object from which the data can be read. C<$flags> is currently unused
and defaults to 0. The mimetype of the screenshot is returned
-=item @vcpuinfo = $dom->get_vcpu_info()
+=item @vcpuinfo = $dom->get_vcpu_info($flags=0)
Obtain information about the state of all virtual CPUs in a running
guest domain. The returned list will have one element for each vCPU,
@@ -1124,7 +1124,9 @@ time of the vCPU, C<state> the running state and C<affinity> giving
the allowed shedular placement. The value for C<affinity> is a
string representing a bitmask against physical CPUs, 8 cpus per
character. To extract the bits use the C<unpack> function with
-the C<b*> template.
+the C<b*> template. NB The C<state>, C<cpuTime>, C<cpu> values are
+only available if using C<$flags> value of 0, and the domain is
+currently running; otherwise they will all be set to zero.
=item $dom->pin_vcpu($vcpu, $mask)