[libvirt] NBD server for libvirt domains using virDomainBlockPeek
by Richard W.M. Jones
This might be of interest to developers on this list. I've written an
NBD server which can serve libvirt guest disks. It uses the
virDomainBlockPeek API and so is necessarily read-only.
https://github.com/libguestfs/nbdkit
https://github.com/libguestfs/nbdkit/tree/master/plugins/libvirt
Example:
$ sudo ./src/nbdkit ./plugins/libvirt/.libs/libnbdkit-libvirt-plugin.so domain=f18x64 disk=vda -f -v
In another window:
$ guestfish --format=raw -a nbd://localhost -i
Welcome to guestfish, the guest filesystem shell for
editing virtual machine filesystems and disk images.
Type: 'help' for help on commands
'man' to read the manual
'quit' to quit the shell
Operating system: Fedora release 18 (Spherical Cow)
/dev/fedora/root mounted on /
/dev/sda1 mounted on /boot
><fs> ll /
total 90
dr-xr-xr-x. 18 root root 4096 Jan 9 17:14 .
drwxr-xr-x 23 1000 1000 4096 Jun 21 15:24 ..
lrwxrwxrwx. 1 root root 7 Jan 9 17:14 bin -> usr/bin
dr-xr-xr-x. 5 root root 1024 Mar 13 23:00 boot
drwxr-xr-x. 2 root root 4096 Feb 11 20:15 dev
drwxr-xr-x. 129 root root 12288 Mar 14 15:22 etc
drwxr-xr-x. 3 root root 4096 Feb 11 20:23 home
lrwxrwxrwx. 1 root root 7 Jan 9 17:14 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Jan 9 17:14 lib64 -> usr/lib64
drwx------. 2 root root 16384 Jan 9 17:12 lost+found
drwxr-xr-x. 2 root root 4096 Jul 19 2012 media
drwxr-xr-x. 4 root root 4096 Feb 12 08:59 mnt
drwxr-xr-x. 2 root root 4096 Jul 19 2012 opt
drwxr-xr-x. 2 root root 4096 Feb 11 20:15 proc
dr-xr-x---. 6 root root 4096 Mar 13 22:55 root
drwxr-xr-x. 26 root root 4096 Feb 11 20:20 run
lrwxrwxrwx. 1 root root 8 Jan 9 17:14 sbin -> usr/sbin
drwxr-xr-x. 2 root root 4096 Jul 19 2012 srv
drwxr-xr-x. 2 root root 4096 Feb 11 20:15 sys
drwxrwxrwt. 16 root root 4096 Mar 13 23:00 tmp
drwxr-xr-x. 13 root root 4096 Jan 9 17:14 usr
drwxr-xr-x. 19 root root 4096 Jan 9 17:17 var
><fs> cat /etc/redhat-release
Fedora release 18 (Spherical Cow)
><fs>
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
11 years, 5 months
[libvirt] [PATCH] snapshot: fix snapshot-delete option check error
by Guannan Ren
For descendant of a snapshot, we need to check if they are
external for both flag VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN and
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY
For the snapshot itself, only check it if
VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN is given.
---
src/qemu/qemu_driver.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index c886378..3a64c43 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12873,10 +12873,11 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
goto cleanup;
if (!metadata_only) {
- if (!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) &&
+ if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) &&
virDomainSnapshotIsExternal(snap))
external++;
- if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN)
+ if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
+ VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY))
virDomainSnapshotForEachDescendant(snap,
qemuDomainSnapshotCountExternal,
&external);
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH v4] qemu: add hv_vapic and hv_spinlocks support
by Ján Tomko
Add new CPU flags for HyperV:
hv_vapic for virtual APIC support
hv_spinlocks for spinlock support
XML:
<features>
<hyperv>
<vapic state='on'/>
<spinlocks state='on'>0xFFFF</spinlocks>
</hyperv>
</features>
results in the following QEMU command line:
qemu -cpu <cpu_model>,hv_vapic,hv_spinlocks=0xffff
https://bugzilla.redhat.com/show_bug.cgi?id=784836
---
v1:
https://www.redhat.com/archives/libvir-list/2013-May/msg00173.html
v2:
https://www.redhat.com/archives/libvir-list/2013-May/msg00184.html
uses virStringSplit instead of strsep
added a missing break to virDomainDefParseXML
v3:
https://www.redhat.com/archives/libvir-list/2013-June/msg00228.html
rebased to use VIR_STRDUP
fixed a crash on parsing '-cpu qemu32,hv_'
v4:
Added state attribute to spinlocks.
CPU command line parsing refactoring is already pushed.
Changed version in docs from 1.0.6 to 1.0.7.
Use 'value' instead of 'hv_tokens[1]' for readability.
docs/formatdomain.html.in | 17 ++++++-
docs/schemas/domaincommon.rng | 13 ++++++
src/conf/domain_conf.c | 62 ++++++++++++++++++++++++-
src/conf/domain_conf.h | 3 ++
src/qemu/qemu_command.c | 48 ++++++++++++++++++-
tests/qemuxml2argvdata/qemuxml2argv-hyperv.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml | 2 +
7 files changed, 142 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 755d084..525e4cd 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1147,6 +1147,8 @@
<privnet/>
<hyperv>
<relaxed state='on'/>
+ <vapic state='on'/>
+ <spinlocks state='on'>0xFFFF</spinlocks>
</hyperv>
</features>
@@ -1197,14 +1199,27 @@
<th>Feature</th>
<th>Description</th>
<th>Value</th>
+ <th>Since</th>
</tr>
<tr>
<td>relaxed</td>
<td>Relax contstraints on timers</td>
<td> on, off</td>
+ <td><span class="since">1.0.0 (QEMU only)</span></td>
+ </tr>
+ <tr>
+ <td>vapic</td>
+ <td>Enable virtual APIC</td>
+ <td>on, off</td>
+ <td><span class="since">1.0.7 (QEMU only)</span></td>
+ </tr>
+ <tr>
+ <td>spinlocks</td>
+ <td>Enable spinlock support</td>
+ <td>hexadecimal number of retries, at least 0xFFF</td>
+ <td><span class="since">1.0.7 (QEMU only)</span></td>
</tr>
</table>
- <span class="since">Since 1.0.0 (QEMU only)</span>
</dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 1eb2f68..a5e69e2 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -4015,6 +4015,19 @@
<ref name="hypervtristate"/>
</element>
</optional>
+ <optional>
+ <element name="vapic">
+ <ref name="hypervtristate"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="spinlocks">
+ <ref name="hypervtristate"/>
+ <data type="string">
+ <param name="pattern">0x[0-9a-fA-F]{0,8}</param>
+ </data>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2373397..5618c4c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -149,7 +149,9 @@ VIR_ENUM_IMPL(virDomainFeatureState, VIR_DOMAIN_FEATURE_STATE_LAST,
"off")
VIR_ENUM_IMPL(virDomainHyperv, VIR_DOMAIN_HYPERV_LAST,
- "relaxed")
+ "relaxed",
+ "vapic",
+ "spinlocks")
VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
"destroy",
@@ -11076,6 +11078,7 @@ virDomainDefParseXML(xmlDocPtr xml,
switch ((enum virDomainHyperv) feature) {
case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
if (!(tmp = virXPathString("string(./@state)", ctxt))) {
virReportError(VIR_ERR_XML_ERROR,
_("missing 'state' attribute for "
@@ -11096,6 +11099,48 @@ virDomainDefParseXML(xmlDocPtr xml,
def->hyperv_features[feature] = value;
break;
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (!(tmp = virXPathString("string(./@state)", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("missing 'state' attribute for "
+ "HyperV Enlightenment feature '%s'"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ if ((value = virDomainFeatureStateTypeFromString(tmp)) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid value of state argument "
+ "for HyperV Enlightenment feature '%s'"),
+ nodes[i]->name);
+ goto error;
+ }
+
+ VIR_FREE(tmp);
+ if (!(tmp = virXPathString("string(.)", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing HyperV spinlock retry count"));
+ goto error;
+ }
+
+ if (virStrToLong_ui(tmp, NULL, 0,
+ &def->hyperv_spinlocks) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Cannot parse HyperV spinlock retry "
+ "count"));
+ goto error;
+ }
+
+ if (def->hyperv_spinlocks < 0xFFF) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("HyperV spinlock retry count must be "
+ "at least 0xFFF"));
+ goto error;
+ }
+ VIR_FREE(tmp);
+ def->hyperv_features[VIR_DOMAIN_HYPERV_SPINLOCKS] = value;
+ break;
+
case VIR_DOMAIN_HYPERV_LAST:
break;
}
@@ -16216,10 +16261,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
switch ((enum virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
if (def->hyperv_features[i])
virBufferAsprintf(buf, " <%s state='%s'/>\n",
virDomainHypervTypeToString(i),
- virDomainFeatureStateTypeToString(def->hyperv_features[i]));
+ virDomainFeatureStateTypeToString(
+ def->hyperv_features[i]));
+ break;
+
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
+ virBufferAsprintf(buf, " <spinlocks state='on'>"
+ "0x%x</spinlocks>\n",
+ def->hyperv_spinlocks);
+ else if (def->hyperv_features[i])
+ virBufferAsprintf(buf, " <spinlocks state='%s'/>",
+ virDomainFeatureStateTypeToString(
+ def->hyperv_features[i]));
break;
case VIR_DOMAIN_HYPERV_LAST:
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5b159ac..3817e37 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1584,6 +1584,8 @@ enum virDomainFeatureState {
enum virDomainHyperv {
VIR_DOMAIN_HYPERV_RELAXED = 0,
+ VIR_DOMAIN_HYPERV_VAPIC,
+ VIR_DOMAIN_HYPERV_SPINLOCKS,
VIR_DOMAIN_HYPERV_LAST
};
@@ -1926,6 +1928,7 @@ struct _virDomainDef {
int apic_eoi;
/* These options are of type virDomainFeatureState */
int hyperv_features[VIR_DOMAIN_HYPERV_LAST];
+ unsigned int hyperv_spinlocks;
virDomainClockDef clock;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 486682e..c6cb833 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5786,11 +5786,18 @@ qemuBuildCpuArgStr(const virQEMUDriverPtr driver,
for (i = 0; i < VIR_DOMAIN_HYPERV_LAST; i++) {
switch ((enum virDomainHyperv) i) {
case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
virBufferAsprintf(&buf, ",hv_%s",
virDomainHypervTypeToString(i));
break;
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ if (def->hyperv_features[i] == VIR_DOMAIN_FEATURE_STATE_ON)
+ virBufferAsprintf(&buf,",hv_spinlocks=0x%x",
+ def->hyperv_spinlocks);
+ break;
+
case VIR_DOMAIN_HYPERV_LAST:
break;
}
@@ -9627,6 +9634,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
{
virCPUDefPtr cpu = NULL;
char **tokens;
+ char **hv_tokens = NULL;
char *model = NULL;
int ret = -1;
int i;
@@ -9706,9 +9714,19 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
goto cleanup;
}
} else if (STRPREFIX(tokens[i], "hv_")) {
- const char *feature = tokens[i] + 3; /* "hv_" */
+ const char *token = tokens[i] + 3; /* "hv_" */
+ const char *feature, *value;
int f;
+ if (*token == '\0')
+ goto syntax;
+
+ if (!(hv_tokens = virStringSplit(token, "=", 2)))
+ goto cleanup;
+
+ feature = hv_tokens[0];
+ value = hv_tokens[1];
+
if (*feature == '\0')
goto syntax;
@@ -9723,12 +9741,39 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
switch ((enum virDomainHyperv) f) {
case VIR_DOMAIN_HYPERV_RELAXED:
+ case VIR_DOMAIN_HYPERV_VAPIC:
+ if (value) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("HyperV feature '%s' should not "
+ "have a value"), feature);
+ goto cleanup;
+ }
dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
break;
+ case VIR_DOMAIN_HYPERV_SPINLOCKS:
+ dom->hyperv_features[f] = VIR_DOMAIN_FEATURE_STATE_ON;
+ if (!value) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("missing HyperV spinlock retry count"));
+ goto cleanup;
+ }
+
+ if (virStrToLong_ui(value, NULL, 0, &dom->hyperv_spinlocks) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("cannot parse HyperV spinlock retry count"));
+ goto cleanup;
+ }
+
+ if (dom->hyperv_spinlocks < 0xFFF)
+ dom->hyperv_spinlocks = 0xFFF;
+ break;
+
case VIR_DOMAIN_HYPERV_LAST:
break;
}
+ virStringFreeList(hv_tokens);
+ hv_tokens = NULL;
}
}
@@ -9756,6 +9801,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom,
cleanup:
VIR_FREE(model);
virStringFreeList(tokens);
+ virStringFreeList(hv_tokens);
return ret;
syntax:
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
index fac4d5f..df6b207 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.args
@@ -1,4 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
--cpu qemu32,hv_relaxed -m 214 -smp 6 -nographic -monitor \
+-cpu qemu32,hv_relaxed,hv_vapic,hv_spinlocks=0x2fff -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-hyperv.xml b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
index 0d5d0c7..13eec63 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hyperv.xml
@@ -12,6 +12,8 @@
<acpi/>
<hyperv>
<relaxed state='on'/>
+ <vapic state='on'/>
+ <spinlocks state='on'>0x2fff</spinlocks>
</hyperv>
</features>
<clock offset='utc'/>
--
1.8.1.5
11 years, 5 months
[libvirt] [PATCH] conf: Requires either uuid or usage of secret
by Osier Yang
As the RNG schema for disk auth secret implies, it requires either
"uuid" or "secret":
<define name='diskAuthSecret'>
<element name='secret'>
<attribute name='type'>
<choice>
<value>ceph</value>
<value>iscsi</value>
</choice>
</attribute>
<choice>
<attribute name='uuid'>
<ref name="UUID"/>
</attribute>
<attribute name='usage'>
<ref name='genericName'/>
</attribute>
</choice>
</element>
</define>
---
src/conf/domain_conf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 2373397..9297937 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4972,6 +4972,14 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
_("only one of uuid and usage can be specified"));
goto error;
}
+
+ if (!authUUID && !authUsage) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("either uuid or usage should be "
+ "specified for a secret"));
+ goto error;
+ }
+
if (authUUID != NULL) {
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_UUID;
if (virUUIDParse(authUUID,
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] qemu: Make probing for commands declarative
by Jiri Denemark
---
src/qemu/qemu_capabilities.c | 53 ++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7cac6e4..c4e076a 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1316,6 +1316,22 @@ struct virQEMUCapsStringFlags {
};
+struct virQEMUCapsStringFlags virQEMUCapsCommands[] = {
+ { "system_wakeup", QEMU_CAPS_WAKEUP },
+ { "transaction", QEMU_CAPS_TRANSACTION },
+ { "block_job_cancel", QEMU_CAPS_BLOCKJOB_SYNC },
+ { "block-job-cancel", QEMU_CAPS_BLOCKJOB_ASYNC },
+ { "dump-guest-memory", QEMU_CAPS_DUMP_GUEST_MEMORY },
+ { "query-spice", QEMU_CAPS_SPICE },
+ { "query-kvm", QEMU_CAPS_KVM },
+ { "block-commit", QEMU_CAPS_BLOCK_COMMIT },
+ { "query-vnc", QEMU_CAPS_VNC },
+ { "drive-mirror", QEMU_CAPS_DRIVE_MIRROR },
+ { "blockdev-snapshot-sync", QEMU_CAPS_DISK_SNAPSHOT },
+ { "add-fd", QEMU_CAPS_ADD_FD },
+ { "nbd-server-start", QEMU_CAPS_NBD_SERVER },
+};
+
struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
{ "BALLOON_CHANGE", QEMU_CAPS_BALLOON_EVENT },
{ "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION },
@@ -1956,42 +1972,15 @@ virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
{
char **commands = NULL;
int ncommands;
- size_t i;
if ((ncommands = qemuMonitorGetCommands(mon, &commands)) < 0)
return -1;
- for (i = 0; i < ncommands; i++) {
- char *name = commands[i];
- if (STREQ(name, "system_wakeup"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_WAKEUP);
- else if (STREQ(name, "transaction"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_TRANSACTION);
- else if (STREQ(name, "block_job_cancel"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_SYNC);
- else if (STREQ(name, "block-job-cancel"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC);
- else if (STREQ(name, "dump-guest-memory"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY);
- else if (STREQ(name, "query-spice"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_SPICE);
- else if (STREQ(name, "query-kvm"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_KVM);
- else if (STREQ(name, "block-commit"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCK_COMMIT);
- else if (STREQ(name, "query-vnc"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC);
- else if (STREQ(name, "drive-mirror"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_MIRROR);
- else if (STREQ(name, "blockdev-snapshot-sync"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_DISK_SNAPSHOT);
- else if (STREQ(name, "add-fd"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_ADD_FD);
- else if (STREQ(name, "nbd-server-start"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_NBD_SERVER);
- VIR_FREE(name);
- }
- VIR_FREE(commands);
+ virQEMUCapsProcessStringFlags(qemuCaps,
+ ARRAY_CARDINALITY(virQEMUCapsCommands),
+ virQEMUCapsCommands,
+ ncommands, commands);
+ virQEMUCapsFreeStringList(ncommands, commands);
/* QMP add-fd was introduced in 1.2, but did not support
* management control of set numbering, and did not have a
--
1.8.2.1
11 years, 5 months
[libvirt] [PATCH] qemu: Make probing for events declarative
by Jiri Denemark
---
src/qemu/qemu_capabilities.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 406dca9..7cac6e4 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1316,6 +1316,11 @@ struct virQEMUCapsStringFlags {
};
+struct virQEMUCapsStringFlags virQEMUCapsEvents[] = {
+ { "BALLOON_CHANGE", QEMU_CAPS_BALLOON_EVENT },
+ { "SPICE_MIGRATE_COMPLETED", QEMU_CAPS_SEAMLESS_MIGRATION },
+};
+
struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "hda-duplex", QEMU_CAPS_HDA_DUPLEX },
{ "hda-micro", QEMU_CAPS_HDA_MICRO },
@@ -2014,21 +2019,15 @@ virQEMUCapsProbeQMPEvents(virQEMUCapsPtr qemuCaps,
{
char **events = NULL;
int nevents;
- size_t i;
if ((nevents = qemuMonitorGetEvents(mon, &events)) < 0)
return -1;
- for (i = 0; i < nevents; i++) {
- char *name = events[i];
-
- if (STREQ(name, "BALLOON_CHANGE"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_BALLOON_EVENT);
- if (STREQ(name, "SPICE_MIGRATE_COMPLETED"))
- virQEMUCapsSet(qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION);
- VIR_FREE(name);
- }
- VIR_FREE(events);
+ virQEMUCapsProcessStringFlags(qemuCaps,
+ ARRAY_CARDINALITY(virQEMUCapsEvents),
+ virQEMUCapsEvents,
+ nevents, events);
+ virQEMUCapsFreeStringList(nevents, events);
return 0;
}
--
1.8.2.1
11 years, 5 months
[libvirt] [PATCH] build: Fix build with -Werror
by Jim Fehlig
Commit 752596b5 broke the build with -Werror
qemu/qemu_hotplug.c: In function 'qemuDomainChangeGraphics':
qemu/qemu_hotplug.c:1980:39: error: declaration of 'listen' shadows a
global declaration [-Werror=shadow]
Fix with s/listen/newlisten/
---
Pushing under the build-breaker rule.
src/qemu/qemu_hotplug.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 637dbc5..18f5fa5 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1977,18 +1977,18 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
}
for (i = 0; i < dev->nListens; i++) {
- virDomainGraphicsListenDefPtr listen = &dev->listens[i];
+ virDomainGraphicsListenDefPtr newlisten = &dev->listens[i];
virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
- if (listen->type != oldlisten->type) {
+ if (newlisten->type != oldlisten->type) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("cannot change the type of listen address"));
goto cleanup;
}
- switch ((enum virDomainGraphicsListenType) listen->type) {
+ switch ((enum virDomainGraphicsListenType) newlisten->type) {
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
- if (STRNEQ_NULLABLE(listen->address, oldlisten->address)) {
+ if (STRNEQ_NULLABLE(newlisten->address, oldlisten->address)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
_("cannot change listen address setting on vnc graphics") :
@@ -1998,7 +1998,7 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
break;
case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
- if (STRNEQ_NULLABLE(listen->network, oldlisten->network)) {
+ if (STRNEQ_NULLABLE(newlisten->network, oldlisten->network)) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
_("cannot change listen network setting on vnc graphics") :
--
1.7.7
11 years, 5 months
[libvirt] [PATCH] network: increase max number of routes
by Laine Stump
This fixes the problem reported in:
https://bugzilla.redhat.com/show_bug.cgi?id=972690
When checking for a collision of a new libvirt network's subnet with
any existing routes, we read all of /proc/net/route into memory, then
parse all the entries. The function that we use to read this file
requires a "maximum length" parameter, which had previously been set
to 64*1024. As each line in /proc/net/route is 128 bytes, this would
allow for a maximum of 512 entries in the routing table.
This patch increases that number to 128 * 100000, which allows for
100,000 routing table entries. This means that it's possible that 12MB
would be allocated, but that would only happen if there really were
100,000 route table entries on the system, it's only held for a very
short time.
Since there is no method of specifying and unlimited max (and that
would create a potential denial of service anyway) hopefully this
limit is large enough to accomodate everyone.
---
src/network/bridge_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index d5886fe..f7c2470 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2305,7 +2305,8 @@ networkCheckRouteCollision(virNetworkObjPtr network)
{
int ret = 0, len;
char *cur, *buf = NULL;
- enum {MAX_ROUTE_SIZE = 1024*64};
+ /* allow for up to 100000 routes (each line is 128 bytes) */
+ enum {MAX_ROUTE_SIZE = 128*100000};
/* Read whole routing table into memory */
if ((len = virFileReadAll(PROC_NET_ROUTE, MAX_ROUTE_SIZE, &buf)) < 0)
--
1.7.11.7
11 years, 5 months
[libvirt] [PATCH v2] qemuDomainChangeGraphics: Check listen address change by listen type
by Michal Privoznik
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
---
src/qemu/qemu_hotplug.c | 70 +++++++++++++++++++++++++++++++------------------
1 file changed, 44 insertions(+), 26 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6c07af5..637dbc5 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1960,10 +1960,9 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
- const char *oldListenAddr, *newListenAddr;
- const char *oldListenNetwork, *newListenNetwork;
int ret = -1;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ size_t i;
if (!olddev) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1971,10 +1970,49 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
goto cleanup;
}
- oldListenAddr = virDomainGraphicsListenGetAddress(olddev, 0);
- newListenAddr = virDomainGraphicsListenGetAddress(dev, 0);
- oldListenNetwork = virDomainGraphicsListenGetNetwork(olddev, 0);
- newListenNetwork = virDomainGraphicsListenGetNetwork(dev, 0);
+ if (dev->nListens != olddev->nListens) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("cannot change the number of listen addresses"));
+ goto cleanup;
+ }
+
+ for (i = 0; i < dev->nListens; i++) {
+ virDomainGraphicsListenDefPtr listen = &dev->listens[i];
+ virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
+
+ if (listen->type != oldlisten->type) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("cannot change the type of listen address"));
+ goto cleanup;
+ }
+
+ switch ((enum virDomainGraphicsListenType) listen->type) {
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
+ if (STRNEQ_NULLABLE(listen->address, oldlisten->address)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
+ _("cannot change listen address setting on vnc graphics") :
+ _("cannot change listen address setting on spice graphics"));
+ goto cleanup;
+ }
+ break;
+
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
+ if (STRNEQ_NULLABLE(listen->network, oldlisten->network)) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
+ _("cannot change listen network setting on vnc graphics") :
+ _("cannot change listen network setting on spice graphics"));
+ goto cleanup;
+ }
+ break;
+
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE:
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST:
+ /* nada */
+ break;
+ }
+ }
switch (dev->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
@@ -1985,16 +2023,6 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
_("cannot change port settings on vnc graphics"));
goto cleanup;
}
- if (STRNEQ_NULLABLE(oldListenAddr,newListenAddr)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen address setting on vnc graphics"));
- goto cleanup;
- }
- if (STRNEQ_NULLABLE(oldListenNetwork,newListenNetwork)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen network setting on vnc graphics"));
- goto cleanup;
- }
if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change keymap setting on vnc graphics"));
@@ -2040,16 +2068,6 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
_("cannot change port settings on spice graphics"));
goto cleanup;
}
- if (STRNEQ_NULLABLE(oldListenAddr, newListenAddr)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen address setting on spice graphics"));
- goto cleanup;
- }
- if (STRNEQ_NULLABLE(oldListenNetwork, newListenNetwork)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen network setting on spice graphics"));
- goto cleanup;
- }
if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
dev->data.spice.keymap)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
--
1.8.1.5
11 years, 5 months
[libvirt] [PATCH] qemuDomainChangeGraphics: Check listen address change by listen type
by Michal Privoznik
Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when an user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.
Therefore, we must take the type of listen address into account as well.
---
src/qemu/qemu_hotplug.c | 71 +++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 26 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6c07af5..8563457 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1960,10 +1960,9 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
virDomainGraphicsDefPtr dev)
{
virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev);
- const char *oldListenAddr, *newListenAddr;
- const char *oldListenNetwork, *newListenNetwork;
int ret = -1;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ size_t i;
if (!olddev) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1971,10 +1970,50 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
goto cleanup;
}
- oldListenAddr = virDomainGraphicsListenGetAddress(olddev, 0);
- newListenAddr = virDomainGraphicsListenGetAddress(dev, 0);
- oldListenNetwork = virDomainGraphicsListenGetNetwork(olddev, 0);
- newListenNetwork = virDomainGraphicsListenGetNetwork(dev, 0);
+ if (dev->nListens != olddev->nListens) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("cannot change the number of listen addresses"));
+ goto cleanup;
+ }
+
+ for (i = 0; i < dev->nListens; i++) {
+ virDomainGraphicsListenDefPtr listen = &dev->listens[i];
+ virDomainGraphicsListenDefPtr oldlisten = &olddev->listens[i];
+
+ if (listen->type != oldlisten->type) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("cannot change the type of listen address"));
+ goto cleanup;
+ }
+
+ switch (listen->type) {
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS:
+ if (STRNEQ_NULLABLE(listen->address, oldlisten->address)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
+ _("cannot change listen address setting on vnc graphics") :
+ _("cannot change listen address setting on spice graphics"));
+ goto cleanup;
+ }
+ break;
+
+ case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK:
+ if (STRNEQ_NULLABLE(listen->network, oldlisten->network)) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ dev->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ?
+ _("cannot change listen network setting on vnc graphics") :
+ _("cannot change listen network setting on spice graphics"));
+ goto cleanup;
+ }
+ break;
+
+ default:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("listen of type %d not handled yet"),
+ listen->type);
+ goto cleanup;
+ }
+ }
switch (dev->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
@@ -1985,16 +2024,6 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
_("cannot change port settings on vnc graphics"));
goto cleanup;
}
- if (STRNEQ_NULLABLE(oldListenAddr,newListenAddr)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen address setting on vnc graphics"));
- goto cleanup;
- }
- if (STRNEQ_NULLABLE(oldListenNetwork,newListenNetwork)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen network setting on vnc graphics"));
- goto cleanup;
- }
if (STRNEQ_NULLABLE(olddev->data.vnc.keymap, dev->data.vnc.keymap)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cannot change keymap setting on vnc graphics"));
@@ -2040,16 +2069,6 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver,
_("cannot change port settings on spice graphics"));
goto cleanup;
}
- if (STRNEQ_NULLABLE(oldListenAddr, newListenAddr)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen address setting on spice graphics"));
- goto cleanup;
- }
- if (STRNEQ_NULLABLE(oldListenNetwork, newListenNetwork)) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot change listen network setting on spice graphics"));
- goto cleanup;
- }
if (STRNEQ_NULLABLE(olddev->data.spice.keymap,
dev->data.spice.keymap)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
--
1.8.1.5
11 years, 5 months