[libvirt] [libvirt-glib] gconfig: Add calls to [gs]et_virt_type to domain tests
by Christophe Fergeau
Setting GVirConfigDomain::virt_type is required for a working
domain configuration, using it in the test programs will be helpful
if people are using this as a base when starting to use libvirt-gconfig
---
examples/config-demo.py | 1 +
libvirt-gconfig/tests/test-domain-create.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/examples/config-demo.py b/examples/config-demo.py
index 508bbc5..268c439 100644
--- a/examples/config-demo.py
+++ b/examples/config-demo.py
@@ -3,6 +3,7 @@
from gi.repository import LibvirtGConfig;
domain = LibvirtGConfig.Domain.new()
+domain.set_virt_type(LibvirtGConfig.DomainVirtType.KVM)
domain.set_name("foo")
domain.set_memory(1024*1024) # 1 GB
domain.set_vcpus(2)
diff --git a/libvirt-gconfig/tests/test-domain-create.c b/libvirt-gconfig/tests/test-domain-create.c
index 20fedc5..e30f643 100644
--- a/libvirt-gconfig/tests/test-domain-create.c
+++ b/libvirt-gconfig/tests/test-domain-create.c
@@ -111,6 +111,9 @@ int main(int argc, char **argv)
domain = gvir_config_domain_new();
g_assert(domain != NULL);
+
+ gvir_config_domain_set_virt_type(domain, GVIR_CONFIG_DOMAIN_VIRT_KVM);
+ g_assert(gvir_config_domain_get_virt_type(domain) == GVIR_CONFIG_DOMAIN_VIRT_KVM);
gvir_config_domain_set_name(domain, "foo");
g_str_const_check(gvir_config_domain_get_name(domain), "foo");
--
1.8.1.4
12 years
[libvirt] [PATCH 1/2] manual: Add info about migrateuri in virsh manual
by Martin Kletzander
The virsh(1) man page wasn't saying anything about the 'migrateuri'
parameter other than it can be usually omitted. A patched version of
docs/migrate.html.in is taken in this patch to fix that up in the man
page.
---
docs/migration.html.in | 4 ++--
tools/virsh.pod | 28 +++++++++++++++++++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/docs/migration.html.in b/docs/migration.html.in
index 2416275..aecef41 100644
--- a/docs/migration.html.in
+++ b/docs/migration.html.in
@@ -192,12 +192,12 @@
should specify the hypervisor specific URI, using an IP address
associated with the network to be used.</li>
<li>The firewall restricts what ports are available. When libvirt
- generates a migration URI will pick a port number using hypervisor
+ generates a migration URI it will pick a port number using hypervisor
specific rules. Some hypervisors only require a single port to be
open in the firewalls, while others require a whole range of port
numbers. In the latter case the management application may wish
to choose a specific port number outside the default range in order
- to comply with local firewall policies</li>
+ to comply with local firewall policies.</li>
</ol>
<h2><a name="config">Configuration file handling</a></h2>
diff --git a/tools/virsh.pod b/tools/virsh.pod
index e7e82e3..11447fe 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1080,7 +1080,7 @@ such as GFS2 or GPFS. If you are sure the migration is safe or you just do not
care, use I<--unsafe> to force the migration.
The I<desturi> is the connection URI of the destination host, and
-I<migrateuri> is the migration URI, which usually can be omitted.
+I<migrateuri> is the migration URI, which usually can be omitted (see below).
I<dname> is used for renaming the domain to new name during migration, which
also usually can be omitted. Likewise, I<--xml> B<file> is usually
omitted, but can be used to supply an alternative XML file for use on
@@ -1108,6 +1108,32 @@ seen from the source machine.
=back
+When I<migrateuri> is not specified, libvirt will automatically determine the
+hypervisor specific URI, by looking up the target host's configured hostname.
+There are a few scenarios where specifying I<migrateuri> may help:
+
+=over 4
+
+=item * The configured hostname is incorrect, or DNS is broken. If a host has a
+hostname which will not resolve to match one of its public IP addresses, then
+libvirt will generate an incorrect URI. In this case I<migrateuri> should be
+explicitly specified, using an IP address, or a correct hostname.
+
+=item * The host has multiple network interaces. If a host has multiple network
+interfaces, it might be desirable for the migration data stream to be sent over
+a specific interface for either security or performance reasons. In this case
+I<migrateuri> should be explicitly specified, using an IP address associated
+with the network to be used.
+
+=item * The firewall restricts what ports are available. When libvirt generates
+a migration URI, it will pick a port number using hypervisor specific rules.
+Some hypervisors only require a single port to be open in the firewalls, while
+others require a whole range of port numbers. In the latter case I<migrateuri>
+might be specified to choose a specific port number outside the default range in
+order to comply with local firewall policies.
+
+=back
+
=item B<migrate-setmaxdowntime> I<domain> I<downtime>
Set maximum tolerable downtime for a domain which is being live-migrated to
--
1.8.1.5
12 years
[libvirt] [PATCHv2 0/4] Add domain modification impact flags to hot-management commands
by Peter Krempa
A respin of the series that changes some virsh commands to handle flags more
sanely. This version fixes comments by Martin, Laine and Eric.
This series omits already acked patches.
Peter Krempa (4):
virsh: Fix semantics of --config for "update-device" command
virsh-domain: Add --live, --config, --current logic to
cmdDetachInterface
virsh-domain: Add --live, --config, --current logic to cmdDetachDevice
virsh-domain: Add --live, --config, --current logic to cmdDetachDisk
tools/virsh-domain.c | 182 +++++++++++++++++++++++++++++++++++++--------------
tools/virsh.pod | 81 +++++++++++++++++------
2 files changed, 194 insertions(+), 69 deletions(-)
--
1.8.1.5
12 years
[libvirt] [PATCH 0/3] Refactor formatting of MAC addresses and domif-getlink virsh command
by Peter Krempa
This series refactors libvirt XML code generator to create uniform
mac addresses with lowercase hex characters and refactors the domif-getlink
command to avoid a bug and too complex code.
Peter Krempa (3):
util: Change virMacAddrFormat to lowercase hex characters
conf: Use virMacAddrFormat while generating domain XML files
virsh-domain-monitor: Refactor cmdDomIfGetLink
src/conf/domain_conf.c | 7 +-
src/util/virmacaddr.c | 2 +-
tests/networkxml2xmlout/bandwidth-network.xml | 2 +-
.../networkxml2xmlout/dhcp6host-routed-network.xml | 2 +-
tests/networkxml2xmlout/empty-allow-ipv6.xml | 2 +-
tests/networkxml2xmlout/isolated-network.xml | 2 +-
tests/networkxml2xmlout/routed-network.xml | 2 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-1.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-2.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-3.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-4.vmx | 4 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-5.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-6.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-ethernet-generated.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-1.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-2.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-3.vmx | 4 +-
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-4.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-ws-in-the-wild-1.vmx | 2 +-
tests/xml2vmxdata/xml2vmx-ws-in-the-wild-2.vmx | 2 +-
tools/virsh-domain-monitor.c | 100 ++++++++-------------
21 files changed, 62 insertions(+), 87 deletions(-)
--
1.8.1.5
12 years
[libvirt] Entering freeze for libvirt-1.0.4
by Daniel Veillard
Based on the discussions from last week, we are entering freeze
now, I tagged v1.0.4-rc1 in git and pushed
libvirt-1.0.4-rc1.tar.gz
as well as rpms for F17 at the usual place:
ftp://libvirt.org/libvirt/
This looks functional for my limited testing, but give it a try.
Hopefully since 1.0.3 wasn't too long ago we should be mostly okay :)
And of course a release on April Fool sounds like a good target !
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
12 years
[libvirt] [PATCHv2] conf: Enforce ranges on cputune variables
by Peter Krempa
The limits are documented at
http://libvirt.org/formatdomain.html#elementsCPUTuning . Enforce them
when going through XML parsing in addition to being enforced by the API.
---
Notes:
Version 2:
- split out from the conf callback series and applied separately to the parser code
src/conf/domain_conf.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f3fca7f..371d80c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9677,6 +9677,14 @@ virDomainDefParseXML(virCapsPtr caps,
goto error;
}
+ if (def->cputune.period > 0 &&
+ (def->cputune.period < 1000 || def->cputune.period > 1000000)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Value of cputune period must be in range "
+ "[1000, 1000000]"));
+ goto error;
+ }
+
if (virXPathLongLong("string(./cputune/quota[1])", ctxt,
&def->cputune.quota) < -1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -9684,6 +9692,15 @@ virDomainDefParseXML(virCapsPtr caps,
goto error;
}
+ if (def->cputune.quota > 0 &&
+ (def->cputune.quota < 1000 ||
+ def->cputune.quota > 18446744073709551)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Value of cputune quota must be in range "
+ "[1000, 18446744073709551]"));
+ goto error;
+ }
+
if (virXPathULongLong("string(./cputune/emulator_period[1])", ctxt,
&def->cputune.emulator_period) < -1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -9691,6 +9708,15 @@ virDomainDefParseXML(virCapsPtr caps,
goto error;
}
+ if (def->cputune.emulator_period > 0 &&
+ (def->cputune.emulator_period < 1000 ||
+ def->cputune.emulator_period > 1000000)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Value of cputune emulator_period must be in range "
+ "[1000, 1000000]"));
+ goto error;
+ }
+
if (virXPathLongLong("string(./cputune/emulator_quota[1])", ctxt,
&def->cputune.emulator_quota) < -1) {
virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -9698,6 +9724,15 @@ virDomainDefParseXML(virCapsPtr caps,
goto error;
}
+ if (def->cputune.emulator_quota > 0 &&
+ (def->cputune.emulator_quota < 1000 ||
+ def->cputune.emulator_quota > 18446744073709551)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Value of cputune emulator_quota must be in range "
+ "[1000, 18446744073709551]"));
+ goto error;
+ }
+
if ((n = virXPathNodeSet("./cputune/vcpupin", ctxt, &nodes)) < 0)
goto error;
--
1.8.1.5
12 years
[libvirt] [PATCH v3] test: Return Libvirt logo as domain screenshot
by Michal Privoznik
This is just a bare Easter Egg. Whenever a user runs virDomainScreenshot
over a domain in test driver, he'll get the Libvirt PNG logo in return.
---
docs/Makefile.am | 1 +
libvirt.spec.in | 1 +
src/test/test_driver.c | 24 ++++++++++++++++++++++++
3 files changed, 26 insertions(+)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 7583772..b5d7575 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -287,6 +287,7 @@ install-data-local:
for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
$(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
done
+ $(INSTALL_DATA) $(srcdir)/../docs/libvirtLogo.png $(DESTDIR)$(pkgdatadir)
uninstall-local:
for h in $(apihtml); do rm $(DESTDIR)$(HTML_DIR)/$$h; done
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 2da0558..34b3f9c 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1941,6 +1941,7 @@ fi
%{_datadir}/libvirt/schemas/storagevol.rng
%{_datadir}/libvirt/cpu_map.xml
+%{_datadir}/libvirt/libvirtLogo.png
%if %{with_systemd}
%{_unitdir}/libvirt-guests.service
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index c5fffb9..4dbd775 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -39,11 +39,13 @@
#include "virutil.h"
#include "viruuid.h"
#include "capabilities.h"
+#include "configmake.h"
#include "viralloc.h"
#include "network_conf.h"
#include "interface_conf.h"
#include "domain_conf.h"
#include "domain_event.h"
+#include "fdstream.h"
#include "storage_conf.h"
#include "node_device_conf.h"
#include "virxml.h"
@@ -5773,6 +5775,27 @@ cleanup:
return ret;
}
+static char *
+testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED,
+ virStreamPtr st,
+ unsigned int screen ATTRIBUTE_UNUSED,
+ unsigned int flags)
+{
+ char *ret = NULL;
+
+ virCheckFlags(0, NULL);
+
+ if (!(ret = strdup("image/png"))) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if (virFDStreamOpenFile(st, PKGDATADIR "/libvirtLogo.png", 0, 0, O_RDONLY < 0))
+ VIR_FREE(ret);
+
+ return ret;
+}
+
static virDriver testDriver = {
.no = VIR_DRV_TEST,
@@ -5843,6 +5866,7 @@ static virDriver testDriver = {
.domainEventDeregisterAny = testDomainEventDeregisterAny, /* 0.8.0 */
.isAlive = testIsAlive, /* 0.9.8 */
.nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */
+ .domainScreenshot = testDomainScreenshot, /* 1.0.5 */
};
static virNetworkDriver testNetworkDriver = {
--
1.8.1.5
12 years
[libvirt] [PATCH] smartcard: spell ccid-card-emulated qemu property correctly
by Eric Blake
Reported by Anthony Messina in
https://bugzilla.redhat.com/show_bug.cgi?id=904692
Present since introduction of smartcard support in commit f5fd9baa
* src/qemu/qemu_command.c (qemuBuildCommandLine): Match qemu spelling.
---
No one has spotted my bug, latent since Feb 2011, until now. I
guess smartcard use is not very common...
src/qemu/qemu_command.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a0c278f..59a6061 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6843,7 +6843,7 @@ qemuBuildCommandLine(virConnectPtr conn,
} else {
database = VIR_DOMAIN_SMARTCARD_DEFAULT_DATABASE;
}
- virBufferAsprintf(&opt, ",database=%s", database);
+ virBufferAsprintf(&opt, ",db=%s", database);
break;
case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
--
1.8.1.4
12 years
[libvirt] [PATCH v5] qemu: Allow migration over IPv6
by Ján Tomko
Allow migration over IPv6 by listening on [::] instead of 0.0.0.0
when QEMU supports it (QEMU_CAPS_IPV6_MIGRATION) and there is
at least one v6 address configured on the system.
Use virURIParse in qemuMigrationPrepareDirect to allow parsing
IPv6 addresses, which would cause an 'incorrect :port' error
message before.
Move setting of migrateFrom from qemuMigrationPrepare{Direct,Tunnel}
after domain XML parsing, since we need the QEMU binary path from it
to get its capabilities.
Bug: https://bugzilla.redhat.com/show_bug.cgi?id=846013
---
diff to v4:
Always listen on IPv6 if it's available.
Don't add a migration flag.
v4:
https://www.redhat.com/archives/libvir-list/2013-March/msg01213.html
discussion:
https://www.redhat.com/archives/libvir-list/2013-March/msg00515.html
src/qemu/qemu_capabilities.c | 6 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_migration.c | 104 +++++++++++++++++++++++++++++++++----------
tests/qemuhelptest.c | 9 ++--
4 files changed, 93 insertions(+), 27 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 3840b41..1e1da4d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -213,6 +213,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"virtio-ccw",
"dtb",
"megasas",
+
+ "ipv6-migration", /* 135 */
);
struct _virQEMUCaps {
@@ -1181,6 +1183,9 @@ virQEMUCapsComputeCmdFlags(const char *help,
if (version >= 11000)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_CPU_HOST);
+ if (version >= 1001000)
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
+
if (version >= 1002000)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
return 0;
@@ -2317,6 +2322,7 @@ virQEMUCapsInitQMPBasic(virQEMUCapsPtr qemuCaps)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_SECCOMP_SANDBOX);
virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_KVM_PIT);
virQEMUCapsSet(qemuCaps, QEMU_CAPS_DTB);
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION);
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 7101f67..2ccc7c2 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -174,6 +174,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_VIRTIO_CCW = 132, /* -device virtio-*-ccw */
QEMU_CAPS_DTB = 133, /* -dtb file */
QEMU_CAPS_SCSI_MEGASAS = 134, /* -device megasas */
+ QEMU_CAPS_IPV6_MIGRATION = 135, /* -incoming [::] */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 537b834..867c7f1 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -22,6 +22,8 @@
#include <config.h>
+#include <netdb.h>
+#include <sys/socket.h>
#include <sys/time.h>
#ifdef WITH_GNUTLS
# include <gnutls/gnutls.h>
@@ -1104,12 +1106,12 @@ error:
*/
static int
qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ const char *listenAddr)
{
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
unsigned short port = 0;
- const char *listenAddr = "0.0.0.0";
char *diskAlias = NULL;
size_t i;
@@ -1980,8 +1982,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
int *cookieoutlen,
const char *dname,
const char *dom_xml,
- const char *migrateFrom,
virStreamPtr st,
+ unsigned int port,
unsigned long flags)
{
virDomainDefPtr def = NULL;
@@ -1997,6 +1999,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
char *xmlout = NULL;
unsigned int cookieFlags;
virCapsPtr caps = NULL;
+ const char *listenAddr = NULL;
+ char *migrateFrom = NULL;
if (virTimeMillisNow(&now) < 0)
return -1;
@@ -2084,6 +2088,45 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
}
}
+ if (tunnel) {
+ /* QEMU will be started with -incoming stdio
+ * (which qemu_command might convert to exec:cat or fd:n)
+ */
+ if (!(migrateFrom = strdup("stdio"))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ virQEMUCapsPtr qemuCaps = NULL;
+ struct addrinfo *info = NULL;
+ struct addrinfo hints = { .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM };
+
+ if (!(qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
+ def->emulator)))
+ goto cleanup;
+
+ /* Listen on :: instead of 0.0.0.0 if QEMU understands it
+ * and there is at least one IPv6 address configured
+ */
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION) &&
+ getaddrinfo("::", NULL, &hints, &info) == 0) {
+ freeaddrinfo(info);
+ listenAddr = "[::]";
+ } else {
+ listenAddr = "0.0.0.0";
+ }
+ virObjectUnref(qemuCaps);
+
+ /* QEMU will be started with -incoming [::]:port
+ * or -incoming 0.0.0.0:port
+ */
+ if (virAsprintf(&migrateFrom, "tcp:%s:%d", listenAddr, port) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
if (!(vm = virDomainObjListAdd(driver->domains,
driver->xmlconf,
def,
@@ -2172,7 +2215,7 @@ done:
if (flags & VIR_MIGRATE_TUNNELLED)
VIR_DEBUG("NBD in tunnelled migration is currently not supported");
else {
- if (qemuMigrationStartNBDServer(driver, vm) < 0) {
+ if (qemuMigrationStartNBDServer(driver, vm, listenAddr) < 0) {
/* error already reported */
goto endjob;
}
@@ -2213,6 +2256,7 @@ done:
ret = 0;
cleanup:
+ VIR_FREE(migrateFrom);
VIR_FREE(origname);
VIR_FREE(xmlout);
virDomainDefFree(def);
@@ -2270,12 +2314,9 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver,
driver, dconn, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, st, NULLSTR(dname), dom_xml, flags);
- /* QEMU will be started with -incoming stdio (which qemu_command might
- * convert to exec:cat or fd:n)
- */
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, dname, dom_xml,
- "stdio", st, flags);
+ st, 0, flags);
return ret;
}
@@ -2296,9 +2337,10 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
static int port = 0;
int this_port;
char *hostname = NULL;
- char migrateFrom [64];
const char *p;
+ char *uri_str = NULL;
int ret = -1;
+ virURIPtr uri;
VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
@@ -2347,16 +2389,39 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
* URI when passing it to the qemu monitor, so bad
* characters in hostname part don't matter.
*/
- if (!STRPREFIX(uri_in, "tcp:")) {
+ if (!(p = STRSKIP(uri_in, "tcp:"))) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("only tcp URIs are supported for KVM/QEMU"
" migrations"));
goto cleanup;
}
- /* Get the port number. */
- p = strrchr(uri_in, ':');
- if (p == strchr(uri_in, ':')) {
+ /* Convert uri_in to well-formed URI with // after tcp: */
+ if (!(STRPREFIX(uri_in, "tcp://"))) {
+ if (virAsprintf(&uri_str, "tcp://%s", p) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ uri = virURIParse(uri_str ? uri_str : uri_in);
+ VIR_FREE(uri_str);
+
+ if (uri == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, _("unable to parse URI: %s"),
+ uri_in);
+ goto cleanup;
+ }
+
+ if (uri->server == NULL) {
+ virReportError(VIR_ERR_INVALID_ARG, _("missing host in migration"
+ " URI: %s"), uri_in);
+ goto cleanup;
+ } else {
+ hostname = uri->server;
+ }
+
+ if (uri->port == 0) {
/* Generate a port */
this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
if (port == QEMUD_MIGRATION_NUM_PORTS)
@@ -2369,25 +2434,16 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
}
} else {
- p++; /* definitely has a ':' in it, see above */
- this_port = virParseNumber(&p);
- if (this_port == -1 || p-uri_in != strlen(uri_in)) {
- virReportError(VIR_ERR_INVALID_ARG,
- "%s", _("URI ended with incorrect ':port'"));
- goto cleanup;
- }
+ this_port = uri->port;
}
}
if (*uri_out)
VIR_DEBUG("Generated uri_out=%s", *uri_out);
- /* QEMU will be started with -incoming tcp:0.0.0.0:port */
- snprintf(migrateFrom, sizeof(migrateFrom), "tcp:0.0.0.0:%d", this_port);
-
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, dname, dom_xml,
- migrateFrom, NULL, flags);
+ NULL, this_port, flags);
cleanup:
VIR_FREE(hostname);
if (ret != 0)
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index a28109a..05bb8a6 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -812,7 +812,8 @@ mymain(void)
QEMU_CAPS_DEVICE_VMWARE_SVGA,
QEMU_CAPS_DEVICE_USB_SERIAL,
QEMU_CAPS_DEVICE_USB_NET,
- QEMU_CAPS_DTB);
+ QEMU_CAPS_DTB,
+ QEMU_CAPS_IPV6_MIGRATION);
DO_TEST("qemu-1.2.0", 1002000, 0, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -913,7 +914,8 @@ mymain(void)
QEMU_CAPS_DEVICE_USB_SERIAL,
QEMU_CAPS_DEVICE_USB_NET,
QEMU_CAPS_DTB,
- QEMU_CAPS_SCSI_MEGASAS);
+ QEMU_CAPS_SCSI_MEGASAS,
+ QEMU_CAPS_IPV6_MIGRATION);
DO_TEST("qemu-kvm-1.2.0", 1002000, 1, 0,
QEMU_CAPS_VNC_COLON,
QEMU_CAPS_NO_REBOOT,
@@ -1019,7 +1021,8 @@ mymain(void)
QEMU_CAPS_DEVICE_USB_SERIAL,
QEMU_CAPS_DEVICE_USB_NET,
QEMU_CAPS_DTB,
- QEMU_CAPS_SCSI_MEGASAS);
+ QEMU_CAPS_SCSI_MEGASAS,
+ QEMU_CAPS_IPV6_MIGRATION);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.8.1.5
12 years
[libvirt] [PATCH] qemu: Support multiple queue virtio-scsi
by Osier Yang
This introduce a new attribute "num_queues" (same with the good name
QEMU uses) for virtio-scsi controller. An example of the XML:
<controller type='scsi' index='0' model='virtio-scsi' num_queues='8'/>
The corresponding QEMU command line:
-device virtio-scsi-pci,id=scsi0,num_queues=8,bus=pci.0,addr=0x3 \
---
docs/formatdomain.html.in | 9 +++++---
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 13 +++++++++++
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 11 +++++++++
.../qemuxml2argv-disk-virtio-scsi-num_queues.args | 8 +++++++
.../qemuxml2argv-disk-virtio-scsi-num_queues.xml | 26 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 3 +++
tests/qemuxml2xmltest.c | 1 +
9 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index cf382e8..262f1ac 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2092,10 +2092,13 @@
controller. A "scsi" controller has an optional
attribute <code>model</code>, which is one of "auto", "buslogic",
"ibmvscsi", "lsilogic", "lsisas1068", "lsisas1078", "virtio-scsi" or
- "vmpvscsi". A "usb" controller has an optional attribute
+ "vmpvscsi". The attribute <code>num_queues</code>
+ (<span class="since">1.0.5 (QEMU and KVM only)</span>) is to specify
+ the number of queues for the controller, it should match the number
+ of vCPUs. A "usb" controller has an optional attribute
<code>model</code>, which is one of "piix3-uhci", "piix4-uhci", "ehci",
- "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3",
- "vt82c686b-uhci", "pci-ohci" or "nec-xhci". Additionally,
+ "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3", "vt82c686b-uhci",
+ "pci-ohci" or "nec-xhci". Additionally,
<span class="since">since 0.10.0</span>, if the USB bus needs to be
explicitly disabled for the guest, <code>model='none'</code> may be used.
The PowerPC64 "spapr-vio" addresses do not have an associated controller.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8d7e6db..089be6c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1407,6 +1407,11 @@
</attribute>
</optional>
<optional>
+ <attribute name="num_queues">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ <optional>
<ref name="usbmaster"/>
</optional>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f3fca7f..e9d6b8b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4825,6 +4825,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
char *type = NULL;
char *idx = NULL;
char *model = NULL;
+ char *num_queues = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -4860,6 +4861,14 @@ virDomainControllerDefParseXML(xmlNodePtr node,
def->model = -1;
}
+ if ((num_queues = virXMLPropString(node, "num_queues"))) {
+ if (virStrToLong_ui(num_queues, NULL, 10, &def->num_queues) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Malformed 'num_queues' value '%s'"), num_queues);
+ goto error;
+ }
+ }
+
if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
goto error;
@@ -4937,6 +4946,7 @@ cleanup:
VIR_FREE(type);
VIR_FREE(idx);
VIR_FREE(model);
+ VIR_FREE(num_queues);
return def;
@@ -13037,6 +13047,9 @@ virDomainControllerDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " model='%s'", model);
}
+ if (def->num_queues)
+ virBufferAsprintf(buf, " num_queues='%u'", def->num_queues);
+
switch (def->type) {
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
if (def->opts.vioserial.ports != -1) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index edddf25..8e79961 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -728,6 +728,7 @@ struct _virDomainControllerDef {
int type;
int idx;
int model; /* -1 == undef */
+ unsigned int num_queues;
union {
virDomainVirtioSerialOpts vioserial;
} opts;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a0c278f..bc7beff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3530,6 +3530,14 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
virBuffer buf = VIR_BUFFER_INITIALIZER;
int model;
+ if (def->num_queues &&
+ !(def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI &&
+ def->model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_VIRTIO_SCSI)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("'num_queues' is only supported by virtio-scsi controller"));
+ return NULL;
+ }
+
switch (def->type) {
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
model = def->model;
@@ -3613,6 +3621,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
goto error;
}
+ if (def->num_queues)
+ virBufferAsprintf(&buf, ",num_queues=%u", def->num_queues);
+
if (qemuBuildDeviceAddressStr(&buf, &def->info, qemuCaps) < 0)
goto error;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.args
new file mode 100644
index 0000000..8d46799
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.args
@@ -0,0 +1,8 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
+/usr/bin/qemu -S -M pc -m 214 -smp 8 -nographic -nodefconfig -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device virtio-scsi-pci,id=scsi0,num_queues=8,bus=pci.0,addr=0x3 \
+-usb \
+-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-scsi0-0-0-0 \
+-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.xml
new file mode 100644
index 0000000..dfa9cf1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-virtio-scsi-num_queues.xml
@@ -0,0 +1,26 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>8</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sdb' bus='scsi'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='scsi' index='0' model='virtio-scsi' num_queues='8'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 38787ac..055d935 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -550,6 +550,9 @@ mymain(void)
DO_TEST("disk-scsi-virtio-scsi",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_VIRTIO_SCSI);
+ DO_TEST("disk-virtio-scsi-num_queues",
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
+ QEMU_CAPS_VIRTIO_SCSI);
DO_TEST("disk-scsi-megasas",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_SCSI_MEGASAS);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ba9aa96..e5056f1 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -179,6 +179,7 @@ mymain(void)
DO_TEST("disk-scsi-device");
DO_TEST("disk-scsi-vscsi");
DO_TEST("disk-scsi-virtio-scsi");
+ DO_TEST("disk-virtio-scsi-num_queues");
DO_TEST("disk-scsi-megasas");
DO_TEST_FULL("disk-mirror", false, WHEN_ACTIVE);
DO_TEST_FULL("disk-mirror", true, WHEN_INACTIVE);
--
1.8.1.4
12 years