[libvirt] [PATCH 0/2] Bulk stats APIs
by Peter Krempa
Unfortunately I wasn't able to finish the virsh and qemu driver IMPL but as the
release is closer than I'd like I'm sending this out for an early review pass.
Thanks in advance for any takers.
Peter Krempa (2):
lib: Introduce API for retrieving bulk domain stats
remote: Implement bulk domain stats APIs in the remote driver
daemon/remote.c | 91 ++++++++++++++++++++++
include/libvirt/libvirt.h.in | 26 +++++++
src/driver.h | 9 +++
src/libvirt.c | 179 +++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 7 ++
src/remote/remote_driver.c | 88 +++++++++++++++++++++
src/remote/remote_protocol.x | 26 ++++++-
src/remote_protocol-structs | 23 ++++++
8 files changed, 448 insertions(+), 1 deletion(-)
--
2.0.2
10 years, 4 months
[libvirt] [PATCH] blkdeviotune: check for overflow when parsing XML
by Erik Skultety
According to docs/schemas/domaincommon.rng and _virDomainBlockIoTuneInfo
all the iotune values are interpreted as unsigned long long, however
according to qemu_monitor_json.c, qemu silently truncates numbers
larger than LLONG_MAX. There's really not much of a usage for such
large numbers anyway yet. This patch provides the same overflow
check during domain XML parsing phase as it does during setting
a blkdeviotune element in qemu_driver.c and thus reports an error when
a larger number than LLONG_MAX is detected.
---
src/conf/domain_conf.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 22a7f7e..4cc900f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5711,6 +5711,18 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
def->blkdeviotune.write_iops_sec = 0;
}
+ if (def->blkdeviotune.total_bytes_sec > LLONG_MAX ||
+ def->blkdeviotune.read_bytes_sec > LLONG_MAX ||
+ def->blkdeviotune.write_bytes_sec > LLONG_MAX ||
+ def->blkdeviotune.total_iops_sec > LLONG_MAX ||
+ def->blkdeviotune.read_iops_sec > LLONG_MAX ||
+ def->blkdeviotune.write_iops_sec > LLONG_MAX) {
+ virReportError(VIR_ERR_OVERFLOW,
+ _("block I/O throttle limit must "
+ "be less than %llu"), LLONG_MAX);
+ goto error;
+ }
+
if ((def->blkdeviotune.total_bytes_sec &&
def->blkdeviotune.read_bytes_sec) ||
(def->blkdeviotune.total_bytes_sec &&
--
1.9.3
10 years, 4 months
[libvirt] [PATCH] virsh: Initialize vshData in cmdMigrate
by Ján Tomko
If the virConnect did not succeeed, we called
virConnectClose on uninitialized data.
Introduced by commit 7eabd55.
---
tools/virsh-domain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Pushed as trivial.
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 2562326..fcfbf74 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9122,7 +9122,7 @@ cmdMigrate(vshControl *ctl, const vshCmd *cmd)
bool functionReturn = false;
int timeout = 0;
bool live_flag = false;
- vshCtrlData data;
+ vshCtrlData data = { .dconn = NULL };
if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
return false;
--
1.8.5.5
10 years, 4 months
[libvirt] Mentors wanted for Outreach Program for Women October 2014
by Stefan Hajnoczi
Dear mentors and core contributors,
Outreach Program for Women is starting the next round in October 2014.
OPW funds women to work on open source software for 12 weeks with the
help of mentors:
https://wiki.gnome.org/OutreachProgramForWomen/
We just completed a successful round of OPW and Google Summer of Code.
Other organizations have also been participating successfully in OPW
like the Linux kernel with Greg KH and other mentors.
Would you like to mentor in OPW October 2014?
Regular code contributors to QEMU, KVM, and libvirt are eligible to
participate as mentors.
We also need project ideas that are achievable in 12 weeks by someone
skilled in programming but not necessarily familiar with open source
or our codebase. Ideas welcome!
Stefan
10 years, 4 months
[libvirt] [PATCH] storage: remove unused 'canonPath' in virStorageFileGetMetadata
by Chen Fan
Signed-off-by: Chen Fan <chen.fan.fnst(a)cn.fujitsu.com>
---
src/storage/storage_driver.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 3604613..5ddc23a 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -2892,7 +2892,6 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
src->path, src->format, (int)uid, (int)gid, allow_probe);
virHashTablePtr cycle = NULL;
- char *canonPath = NULL;
int ret = -1;
if (!(cycle = virHashCreate(5, NULL)))
@@ -2904,7 +2903,6 @@ virStorageFileGetMetadata(virStorageSourcePtr src,
ret = virStorageFileGetMetadataRecurse(src, uid, gid,
allow_probe, cycle);
- VIR_FREE(canonPath);
virHashFree(cycle);
return ret;
}
--
1.9.3
10 years, 4 months
[libvirt] [PATCH v2] Add new 'kvm' domain feature and ability to hide KVM signature
by Alex Williamson
QEMU 2.1 added support for the kvm=off option to the -cpu command,
allowing the KVM hypervisor signature to be hidden from the guest.
This enables disabling of some paravirualization features in the
guest as well as allowing certain drivers which test for the
hypervisor to load. Domain XML syntax is as follows:
<domain type='kvm>
...
<features>
...
<kvm>
<hidden state='on'/>
</kvm>
</features>
...
Signed-off-by: Alex Williamson <alex.williamson(a)redhat.com>
---
Hearing no further comments, here's v2:
- white space fix in docs/formatdomain.html.in
- s/virBufferAsprintf/virBufferAddLit/ in src/qemu/qemu_command.c
docs/formatdomain.html.in | 21 ++++
docs/schemas/domaincommon.rng | 18 +++-
src/conf/domain_conf.c | 100 ++++++++++++++++++++
src/conf/domain_conf.h | 9 ++
src/qemu/qemu_command.c | 22 ++++
tests/qemuargv2xmltest.c | 2
.../qemuxml2argv-kvm-features-off.args | 5 +
.../qemuxml2argv-kvm-features-off.xml | 27 +++++
.../qemuxml2argv-kvm-features.args | 5 +
.../qemuxml2argvdata/qemuxml2argv-kvm-features.xml | 27 +++++
tests/qemuxml2argvtest.c | 3 +
tests/qemuxml2xmltest.c | 3 +
12 files changed, 240 insertions(+), 2 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index bd99ae0..bcc0bbd 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1232,6 +1232,9 @@
<vapic state='on'/>
<spinlocks state='on' retries='4096'/>
</hyperv>
+ <kvm>
+ <hidden state='on'/>
+ </kvm>
<pvspinlock/>
</features>
@@ -1310,7 +1313,23 @@
can be explicitly disabled by using <code>state='off'</code>
attribute.
</dd>
-
+ <dt><code>kvm</code></dt>
+ <dd>Various features to change the behavior of the KVM hypervisor.
+ <table class="top_table">
+ <tr>
+ <th>Feature</th>
+ <th>Description</th>
+ <th>Value</th>
+ <th>Since</th>
+ </tr>
+ <tr>
+ <td>hidden</td>
+ <td>Hide the KVM hypervisor from standard MSR based discovery</td>
+ <td>on, off</td>
+ <td><span class="since">2.1.0 (QEMU only)</span></td>
+ </tr>
+ </table>
+ </dd>
</dl>
<h3><a name="elementsTime">Time keeping</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 033f2f6..5c99a14 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3826,7 +3826,7 @@
</define>
<!--
A set of optional features: PAE, APIC, ACPI,
- HyperV Enlightenment, paravirtual spinlocks and HAP support
+ HyperV Enlightenment, KVM features, paravirtual spinlocks and HAP support
-->
<define name="features">
<optional>
@@ -3868,6 +3868,9 @@
</element>
</optional>
<optional>
+ <ref name="kvm"/>
+ </optional>
+ <optional>
<element name="privnet">
<empty/>
</element>
@@ -4472,6 +4475,19 @@
</element>
</define>
+ <!-- Optional KVM features -->
+ <define name="kvm">
+ <element name="kvm">
+ <interleave>
+ <optional>
+ <element name="hidden">
+ <ref name="featurestate"/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<!-- Optional capabilities features -->
<define name="capabilities">
<element name="capabilities">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 934f6cb..8b0bdb0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -142,6 +142,7 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
"viridian",
"privnet",
"hyperv",
+ "kvm",
"pvspinlock",
"capabilities")
@@ -155,6 +156,9 @@ VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
"vapic",
"spinlocks")
+VIR_ENUM_IMPL(virDomainKVM, VIR_DOMAIN_KVM_LAST,
+ "hidden")
+
VIR_ENUM_IMPL(virDomainCapsFeature, VIR_DOMAIN_CAPS_FEATURE_LAST,
"audit_control",
"audit_write",
@@ -12168,6 +12172,7 @@ virDomainDefParseXML(xmlDocPtr xml,
case VIR_DOMAIN_FEATURE_VIRIDIAN:
case VIR_DOMAIN_FEATURE_PRIVNET:
case VIR_DOMAIN_FEATURE_HYPERV:
+ case VIR_DOMAIN_FEATURE_KVM:
def->features[val] = VIR_TRISTATE_SWITCH_ON;
break;
@@ -12295,6 +12300,54 @@ virDomainDefParseXML(xmlDocPtr xml,
ctxt->node = node;
}
+ if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
+ int feature;
+ int value;
+ node = ctxt->node;
+ if ((n = virXPathNodeSet("./features/kvm/*", ctxt, &nodes)) < 0)
+ goto error;
+
+ for (i = 0; i < n; i++) {
+ feature = virDomainKVMTypeFromString((const char *)nodes[i]->name);
+ if (feature < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported KVM feature: %s"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ ctxt->node = nodes[i];
+
+ switch ((virDomainKVM) feature) {
+ case VIR_DOMAIN_KVM_HIDDEN:
+ if (!(tmp = virXPathString("string(./@state)", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("missing 'state' attribute for "
+ "KVM feature '%s'"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ if ((value = virTristateSwitchTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid value of state argument "
+ "for KVM feature '%s'"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ VIR_FREE(tmp);
+ def->kvm_features[feature] = value;
+ break;
+
+ case VIR_DOMAIN_KVM_LAST:
+ break;
+ }
+ }
+ VIR_FREE(nodes);
+ ctxt->node = node;
+ }
+
if ((n = virXPathNodeSet("./features/capabilities/*", ctxt, &nodes)) < 0)
goto error;
@@ -14303,6 +14356,29 @@ virDomainDefFeaturesCheckABIStability(virDomainDefPtr src,
}
}
+ /* kvm */
+ if (src->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
+ for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
+ switch ((virDomainKVM) i) {
+ case VIR_DOMAIN_KVM_HIDDEN:
+ if (src->kvm_features[i] != dst->kvm_features[i]) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("State of KVM feature '%s' differs: "
+ "source: '%s', destination: '%s'"),
+ virDomainKVMTypeToString(i),
+ virTristateSwitchTypeToString(src->kvm_features[i]),
+ virTristateSwitchTypeToString(dst->kvm_features[i]));
+ return false;
+ }
+
+ break;
+
+ case VIR_DOMAIN_KVM_LAST:
+ break;
+ }
+ }
+ }
+
return true;
}
@@ -18133,6 +18209,30 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virBufferAddLit(buf, "</hyperv>\n");
break;
+ case VIR_DOMAIN_FEATURE_KVM:
+ if (def->features[i] != VIR_TRISTATE_SWITCH_ON)
+ break;
+
+ virBufferAddLit(buf, "<kvm>\n");
+ virBufferAdjustIndent(buf, 2);
+ for (j = 0; j < VIR_DOMAIN_KVM_LAST; j++) {
+ switch ((virDomainKVM) j) {
+ case VIR_DOMAIN_KVM_HIDDEN:
+ if (def->kvm_features[j])
+ virBufferAsprintf(buf, "<%s state='%s'/>\n",
+ virDomainKVMTypeToString(j),
+ virTristateSwitchTypeToString(
+ def->kvm_features[j]));
+ break;
+
+ case VIR_DOMAIN_KVM_LAST:
+ break;
+ }
+ }
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</kvm>\n");
+ break;
+
case VIR_DOMAIN_FEATURE_CAPABILITIES:
if (def->features[i] == VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT &&
!virDomainDefHasCapabilitiesFeatures(def))
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ff7d640..cca9c0f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1515,6 +1515,7 @@ typedef enum {
VIR_DOMAIN_FEATURE_VIRIDIAN,
VIR_DOMAIN_FEATURE_PRIVNET,
VIR_DOMAIN_FEATURE_HYPERV,
+ VIR_DOMAIN_FEATURE_KVM,
VIR_DOMAIN_FEATURE_PVSPINLOCK,
VIR_DOMAIN_FEATURE_CAPABILITIES,
@@ -1530,6 +1531,12 @@ typedef enum {
} virDomainHyperv;
typedef enum {
+ VIR_DOMAIN_KVM_HIDDEN = 0,
+
+ VIR_DOMAIN_KVM_LAST
+} virDomainKVM;
+
+typedef enum {
VIR_DOMAIN_CAPABILITIES_POLICY_DEFAULT = 0,
VIR_DOMAIN_CAPABILITIES_POLICY_ALLOW,
VIR_DOMAIN_CAPABILITIES_POLICY_DENY,
@@ -1943,6 +1950,7 @@ struct _virDomainDef {
int features[VIR_DOMAIN_FEATURE_LAST];
int apic_eoi;
int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+ int kvm_features[VIR_DOMAIN_KVM_LAST];
unsigned int hyperv_spinlocks;
/* These options are of type virTristateSwitch: ON = keep, OFF = drop */
@@ -2626,6 +2634,7 @@ VIR_ENUM_DECL(virDomainGraphicsSpiceStreamingMode)
VIR_ENUM_DECL(virDomainGraphicsSpiceMouseMode)
VIR_ENUM_DECL(virDomainGraphicsVNCSharePolicy)
VIR_ENUM_DECL(virDomainHyperv)
+VIR_ENUM_DECL(virDomainKVM)
VIR_ENUM_DECL(virDomainRNGModel)
VIR_ENUM_DECL(virDomainRNGBackend)
VIR_ENUM_DECL(virDomainTPMModel)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8a69976..d9f4b71 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6228,6 +6228,25 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver,
}
}
+ if (def->features[VIR_DOMAIN_FEATURE_KVM] == VIR_TRISTATE_SWITCH_ON) {
+ if (!have_cpu) {
+ virBufferAdd(&buf, default_model, -1);
+ have_cpu = true;
+ }
+
+ for (i = 0; i < VIR_DOMAIN_KVM_LAST; i++) {
+ switch ((virDomainKVM) i) {
+ case VIR_DOMAIN_KVM_HIDDEN:
+ if (def->kvm_features[i] == VIR_TRISTATE_SWITCH_ON)
+ virBufferAddLit(&buf, ",kvm=off");
+ break;
+
+ case VIR_DOMAIN_KVM_LAST:
+ break;
+ }
+ }
+ }
+
if (virBufferCheckError(&buf) < 0)
goto cleanup;
@@ -10692,6 +10711,9 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
}
virStringFreeList(hv_tokens);
hv_tokens = NULL;
+ } else if (STREQ(tokens[i], "kvm=off")) {
+ dom->features[VIR_DOMAIN_FEATURE_KVM] = VIR_TRISTATE_SWITCH_ON;
+ dom->kvm_features[VIR_DOMAIN_KVM_HIDDEN] = VIR_TRISTATE_SWITCH_ON;
}
}
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 6bad7d6..9c00cd9 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -284,6 +284,8 @@ mymain(void)
DO_TEST("hyperv");
+ DO_TEST("kvm-features");
+
DO_TEST("pseries-nvram");
DO_TEST("pseries-disk");
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args
new file mode 100644
index 0000000..363fd2a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu \
+-S -M pc -cpu qemu32 -m 214 -smp 6 -nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-boot n -usb -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml
new file mode 100644
index 0000000..64b8cd8
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features-off.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <kvm>
+ <hidden state='off'/>
+ </kvm>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args
new file mode 100644
index 0000000..b223951
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.args
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc \
+-cpu qemu32,kvm=off -m 214 -smp 6 -nographic -monitor \
+unix:/tmp/test-monitor,server,nowait -boot n -usb -net none -serial none \
+-parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml
new file mode 100644
index 0000000..3f2817e
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-kvm-features.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219100</memory>
+ <currentMemory unit='KiB'>219100</currentMemory>
+ <vcpu placement='static'>6</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='network'/>
+ </os>
+ <features>
+ <acpi/>
+ <kvm>
+ <hidden state='on'/>
+ </kvm>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 62b969c..427ebfc 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -666,6 +666,9 @@ mymain(void)
DO_TEST("hyperv", NONE);
DO_TEST("hyperv-off", NONE);
+ DO_TEST("kvm-features", NONE);
+ DO_TEST("kvm-features-off", NONE);
+
DO_TEST("hugepages", QEMU_CAPS_MEM_PATH);
DO_TEST("hugepages-pages", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM,
QEMU_CAPS_OBJECT_MEMORY_FILE);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 5941323..3a174c0 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -196,6 +196,9 @@ mymain(void)
DO_TEST("hyperv");
DO_TEST("hyperv-off");
+ DO_TEST("kvm-features");
+ DO_TEST("kvm-features-off");
+
DO_TEST("hugepages");
DO_TEST("hugepages-pages");
DO_TEST("hugepages-pages2");
10 years, 4 months
[libvirt] [PATCHv2] iotune: setting an invalid value now reports error
by Erik Skultety
When trying to set an invalid value into iotune element, standard
behavior was to not report any error, rather to reset all affected
subelements of the iotune element back to 0 which results in ignoring
those particular subelements by XML generator. Patch further
examines the return code of the virXPathULongLong function
and in case of an invalid non-integer value raises an error.
Fixed to preserve consistency with invalid value checking
of other elements.
Resolves https://bugzilla.redhat.com/show_bug.cgi?id=1131811
---
src/conf/domain_conf.c | 67 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 49 insertions(+), 18 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9557020..bf8d30c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5416,6 +5416,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
char *mirrorType = NULL;
int expected_secret_usage = -1;
int auth_secret_usage = -1;
+ int ret = 0;
if (!(def = virDomainDiskDefNew()))
return NULL;
@@ -5644,39 +5645,69 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
goto error;
}
} else if (xmlStrEqual(cur->name, BAD_CAST "iotune")) {
- if (virXPathULongLong("string(./iotune/total_bytes_sec)",
- ctxt,
- &def->blkdeviotune.total_bytes_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/total_bytes_sec)",
+ ctxt,
+ &def->blkdeviotune.total_bytes_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("total throughput limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.total_bytes_sec = 0;
}
- if (virXPathULongLong("string(./iotune/read_bytes_sec)",
- ctxt,
- &def->blkdeviotune.read_bytes_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/read_bytes_sec)",
+ ctxt,
+ &def->blkdeviotune.read_bytes_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("read throughput limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.read_bytes_sec = 0;
}
- if (virXPathULongLong("string(./iotune/write_bytes_sec)",
- ctxt,
- &def->blkdeviotune.write_bytes_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/write_bytes_sec)",
+ ctxt,
+ &def->blkdeviotune.write_bytes_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("write throughput limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.write_bytes_sec = 0;
}
- if (virXPathULongLong("string(./iotune/total_iops_sec)",
- ctxt,
- &def->blkdeviotune.total_iops_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/total_iops_sec)",
+ ctxt,
+ &def->blkdeviotune.total_iops_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("total I/O operations limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.total_iops_sec = 0;
}
- if (virXPathULongLong("string(./iotune/read_iops_sec)",
- ctxt,
- &def->blkdeviotune.read_iops_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/read_iops_sec)",
+ ctxt,
+ &def->blkdeviotune.read_iops_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("read I/O operations limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.read_iops_sec = 0;
}
- if (virXPathULongLong("string(./iotune/write_iops_sec)",
- ctxt,
- &def->blkdeviotune.write_iops_sec) < 0) {
+ ret = virXPathULongLong("string(./iotune/write_iops_sec)",
+ ctxt,
+ &def->blkdeviotune.write_iops_sec);
+ if (ret == -2) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("write I/O operations limit must be an integer"));
+ goto error;
+ } else if (ret < 0) {
def->blkdeviotune.write_iops_sec = 0;
}
--
1.9.3
10 years, 4 months
[libvirt] [PATCH] blockcopy: allow block device destination
by Eric Blake
To date, anyone performing a block copy and pivot ends up with
the destination being treated as <disk type='file'>. While this
works for data access for a block device, it has at least one
noticeable shortcoming: virDomainGetBlockInfo() reports allocation
differently for block devices visited as files (the size of the
device) than for block devices visited as <disk type='block'>
(the maximum sector used, as reported by qemu); and this difference
is significant when trying to manage qcow2 format on block devices
that can be grown as needed.
I still plan to add a virDomainBlockCopy() API that takes the
destination disk as XML, allowing full expressive capability
to copy to a network disk. But a new API can't be backported,
while a new flag to an existing API can. So this patch enhances
blockcopy to let the user flag when the resulting XML after the
copy must list the device as type='block'.
* include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_REBASE_COPY_DEV):
New flag.
* src/libvirt.c (virDomainBlockRebase): Document it.
* tools/virsh-domain.c (opts_block_copy, blockJobImpl): Add
--blockdev option.
* tools/virsh.pod (blockcopy): Document it.
* src/qemu/qemu_driver.c (qemuDomainBlockRebase): Allow new flag.
(qemuDomainBlockCopy): Remember the flag.
* tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml: Test it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
include/libvirt/libvirt.h.in | 2 ++
src/libvirt.c | 8 ++++++--
src/qemu/qemu_driver.c | 12 ++++++++----
.../qemuxml2argvdata/qemuxml2argv-disk-mirror.xml | 4 ++--
tools/virsh-domain.c | 6 ++++++
tools/virsh.pod | 7 +++++--
6 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 47ea695..f2a02ea 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2590,6 +2590,8 @@ typedef enum {
VIR_DOMAIN_BLOCK_REBASE_RELATIVE = 1 << 4, /* Keep backing chain
referenced using relative
names */
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV = 1 << 5, /* Treat destination as block
+ device instead of file */
} virDomainBlockRebaseFlags;
int virDomainBlockRebase(virDomainPtr dom, const char *disk,
diff --git a/src/libvirt.c b/src/libvirt.c
index 992e4f2..c4643e8 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -19881,7 +19881,10 @@ virDomainBlockPull(virDomainPtr dom, const char *disk,
* pre-create files with relative backing file names, rather than the default
* of absolute backing file names; as a security precaution, you should
* generally only use reuse_ext with the shallow flag and a non-raw
- * destination file.
+ * destination file. By default, the copy destination will be treated as
+ * type='file', but using VIR_DOMAIN_BLOCK_REBASE_COPY_DEV treats the
+ * destination as type='block' (affecting how virDomainGetBlockInfo() will
+ * report allocation after pivoting).
*
* A copy job has two parts; in the first phase, the @bandwidth parameter
* affects how fast the source is pulled into the destination, and the job
@@ -19950,7 +19953,8 @@ virDomainBlockRebase(virDomainPtr dom, const char *disk,
virCheckNonNullArgGoto(base, error);
} else if (flags & (VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
- VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)) {
+ VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV)) {
virReportInvalidArg(flags,
_("use of flags in %s requires a copy job"),
__FUNCTION__);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index b6219ba..e74227e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15295,7 +15295,8 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
/* Preliminaries: find the disk we are editing, sanity checks */
virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
- VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT, -1);
+ VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV, -1);
priv = vm->privateData;
cfg = virQEMUDriverGetConfig(driver);
@@ -15374,7 +15375,8 @@ qemuDomainBlockCopy(virDomainObjPtr vm,
if (VIR_ALLOC(mirror) < 0)
goto endjob;
/* XXX Allow non-file mirror destinations */
- mirror->type = VIR_STORAGE_TYPE_FILE;
+ mirror->type = flags & VIR_DOMAIN_BLOCK_REBASE_COPY_DEV ?
+ VIR_STORAGE_TYPE_BLOCK : VIR_STORAGE_TYPE_FILE;
if (format) {
if ((mirror->format = virStorageFileFormatTypeFromString(format)) <= 0) {
@@ -15466,7 +15468,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
VIR_DOMAIN_BLOCK_REBASE_COPY |
VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
- VIR_DOMAIN_BLOCK_REBASE_RELATIVE, -1);
+ VIR_DOMAIN_BLOCK_REBASE_RELATIVE |
+ VIR_DOMAIN_BLOCK_REBASE_COPY_DEV, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
@@ -15482,7 +15485,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
format = "raw";
flags &= ~(VIR_DOMAIN_BLOCK_REBASE_COPY |
VIR_DOMAIN_BLOCK_REBASE_COPY_RAW);
- return qemuDomainBlockCopy(vm, dom->conn, path, base, format, bandwidth, flags);
+ return qemuDomainBlockCopy(vm, dom->conn, path, base, format,
+ bandwidth, flags);
}
return qemuDomainBlockJobImpl(vm, dom->conn, path, base, bandwidth, NULL,
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml
index 46f2a3e..7495a45 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml
@@ -17,8 +17,8 @@
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<backingStore/>
- <mirror type='file' file='/dev/HostVG/QEMUGuest1Copy' job='copy' ready='yes'>
- <source file='/dev/HostVG/QEMUGuest1Copy'/>
+ <mirror type='block' job='copy' ready='yes'>
+ <source dev='/dev/HostVG/QEMUGuest1Copy'/>
</mirror>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' target='0' unit='0'/>
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f7193cb..1fbd36e 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1521,6 +1521,8 @@ blockJobImpl(vshControl *ctl, const vshCmd *cmd,
flags |= VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
if (vshCommandOptBool(cmd, "raw"))
flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW;
+ if (vshCommandOptBool(cmd, "blockdev"))
+ flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_DEV;
if (vshCommandOptStringReq(ctl, cmd, "dest", &base) < 0)
goto cleanup;
ret = virDomainBlockRebase(dom, path, base, bandwidth, flags);
@@ -1828,6 +1830,10 @@ static const vshCmdOptDef opts_block_copy[] = {
.type = VSH_OT_BOOL,
.help = N_("use raw destination file")
},
+ {.name = "blockdev",
+ .type = VSH_OT_BOOL,
+ .help = N_("copy destination is block device instead of regular file")
+ },
{.name = "wait",
.type = VSH_OT_BOOL,
.help = N_("wait for job to reach mirroring phase")
diff --git a/tools/virsh.pod b/tools/virsh.pod
index f07deec..8178868 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -873,7 +873,8 @@ unlimited. The hypervisor can choose whether to reject the value or
convert it to the maximum value allowed.
=item B<blockcopy> I<domain> I<path> I<dest> [I<bandwidth>] [I<--shallow>]
-[I<--reuse-external>] [I<--raw>] [I<--wait> [I<--async>] [I<--verbose>]]
+[I<--reuse-external>] [I<--raw>] [I<--blockdev>]
+[I<--wait> [I<--async>] [I<--verbose>]]
[{I<--pivot> | I<--finish>}] [I<--timeout> B<seconds>]
Copy a disk backing image chain to I<dest>. By default, this command
@@ -891,7 +892,9 @@ The format of the destination is determined by the first match in the
following list: if I<--raw> is specified, it will be raw; if
I<--reuse-external> is specified, the existing destination is probed
for a format; and in all other cases, the destination format will
-match the source format.
+match the source format. The destination is treated as a regular
+file unless I<--blockdev> is used to signal that it is a block
+device.
By default, the copy job runs in the background, and consists of two
phases. Initially, the job must copy all data from the source, and
--
1.7.1
10 years, 4 months
[libvirt] [PATCH] maint: drop spurious semicolons
by Eric Blake
I noticed a line 'int nparams = 0;;' in remote_dispatch.h, and
tracked down where it was generated. While at it, I found a
couple of other double semicolons. Additionally, I noticed that
commit df0b57a95 left a stale reference to the file name
remote_dispatch_bodies.h.
* src/conf/numatune_conf.c (virDomainNumatuneNodeParseXML): Drop
empty statement.
* tests/virdbustest.c (testMessageStruct, testMessageSimple):
Likewise.
* src/rpc/gendispatch.pl (remote_dispatch_bodies.h): Likewise, and
update stale comments.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the trivial rule.
Syntax check can't easily catch this, because we want to allow
'for (int i = 0;; i++)' on a loop that uses break to exit, so
this is just done by manual inspection.
src/conf/numatune_conf.c | 2 +-
src/rpc/gendispatch.pl | 4 ++--
tests/virdbustest.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c
index ff0f3eb..21d9a64 100644
--- a/src/conf/numatune_conf.c
+++ b/src/conf/numatune_conf.c
@@ -81,7 +81,7 @@ virDomainNumatuneNodeParseXML(virDomainNumatunePtr *numatunePtr,
xmlXPathContextPtr ctxt)
{
char *tmp = NULL;
- int n = 0;;
+ int n = 0;
int ret = -1;
size_t i = 0;
virDomainNumatunePtr numatune = *numatunePtr;
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index d820d0e..27093d2 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -380,7 +380,7 @@ if ($mode eq "debug") {
}
}
-# Bodies for dispatch functions ("remote_dispatch_bodies.h").
+# Bodies for dispatch functions ("remote_dispatch.h").
elsif ($mode eq "server") {
my %generate = map { $_ => 1 } @autogen;
my @keys = sort (keys %calls);
@@ -537,7 +537,7 @@ elsif ($mode eq "server") {
push(@args_list, "args->$1.$1_len");
} elsif ($args_member =~ m/^remote_typed_param (\S+)<(\S+)>;/) {
push(@vars_list, "virTypedParameterPtr $1 = NULL");
- push(@vars_list, "int n$1 = 0;");
+ push(@vars_list, "int n$1 = 0");
if ($call->{ProcName} eq "NodeSetMemoryParameters") {
push(@args_list, "priv->conn");
}
diff --git a/tests/virdbustest.c b/tests/virdbustest.c
index a798fbe..0079b41 100644
--- a/tests/virdbustest.c
+++ b/tests/virdbustest.c
@@ -62,7 +62,7 @@ static int testMessageSimple(const void *args ATTRIBUTE_UNUSED)
unsigned int in_uint32 = 200000000, out_uint32 = 0;
long long in_int64 = 1000000000000LL, out_int64 = 0;
unsigned long long in_uint64 = 2000000000000LL, out_uint64 = 0;
- double in_double = 3.14159265359, out_double = 0;;
+ double in_double = 3.14159265359, out_double = 0;
const char *in_string = "Hello World";
char *out_string = NULL;
const char *in_objectpath = "/org/libvirt/test";
@@ -338,7 +338,7 @@ static int testMessageStruct(const void *args ATTRIBUTE_UNUSED)
unsigned int in_uint32 = 200000000, out_uint32 = 0;
long long in_int64 = -1000000000000LL, out_int64 = 0;
unsigned long long in_uint64 = 2000000000000LL, out_uint64 = 0;
- double in_double = 3.14159265359, out_double = 0;;
+ double in_double = 3.14159265359, out_double = 0;
const char *in_string = "Hello World";
char *out_string = NULL;
const char *in_objectpath = "/org/libvirt/test";
--
1.9.3
10 years, 4 months
[libvirt] [PATCH] libxl: fix memory corruption introduced by commit b55cc5f4e
by Jim Fehlig
Commit b55cc5f4e did a shallow copy of libxl_{sdl,vnc}_info from the
domain config to the build info, which resulted in double-freeing
strings contained in the structures during cleanup, which later
resulted in a libvirtd crash. Fix by performing a deep copy of the
structure, VIR_STRDUP'ing embedded strings instead of simply copying
their pointers.
Fixes the following issue reported on the libvirt dev list
https://www.redhat.com/archives/libvir-list/2014-August/msg01112.html
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_conf.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 1210500..1dbdd9c 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1130,10 +1130,24 @@ libxlMakeVfbList(virPortAllocatorPtr graphicsports,
libxl_domain_build_info *b_info = &d_config->b_info;
libxl_device_vfb vfb = d_config->vfbs[0];
- if (libxl_defbool_val(vfb.vnc.enable))
- memcpy(&b_info->u.hvm.vnc, &vfb.vnc, sizeof(libxl_vnc_info));
- else if (libxl_defbool_val(vfb.sdl.enable))
- memcpy(&b_info->u.hvm.sdl, &vfb.sdl, sizeof(libxl_sdl_info));
+ if (libxl_defbool_val(vfb.vnc.enable)) {
+ libxl_defbool_set(&b_info->u.hvm.vnc.enable, true);
+ if (VIR_STRDUP(b_info->u.hvm.vnc.listen, vfb.vnc.listen) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->u.hvm.vnc.passwd, vfb.vnc.passwd) < 0)
+ goto error;
+ b_info->u.hvm.vnc.display = vfb.vnc.display;
+ libxl_defbool_set(&b_info->u.hvm.vnc.findunused,
+ libxl_defbool_val(vfb.vnc.findunused));
+ } else if (libxl_defbool_val(vfb.sdl.enable)) {
+ libxl_defbool_set(&b_info->u.hvm.sdl.enable, true);
+ libxl_defbool_set(&b_info->u.hvm.sdl.opengl,
+ libxl_defbool_val(vfb.sdl.opengl));
+ if (VIR_STRDUP(b_info->u.hvm.sdl.display, vfb.sdl.display) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->u.hvm.sdl.xauthority, vfb.sdl.xauthority) < 0)
+ goto error;
+ }
}
return 0;
--
1.8.4.5
10 years, 4 months