[libvirt] [PATCH 0/4] Introduction of qemucapabilitiestest
by Michal Privoznik
So far, we are testing our capabilities code only from the --help output. Which
is sufficient for ancient qemus, but not sufficient for 99% of qemus, where the
QMP is used. So far, only one (example) test case is being added. If the patch
set is accepted, we can add much more test cases.
Michal Privoznik (4):
qemu_capabilities: Introduce virQEMUCapsInitQMPMonitor
tests: Learn qemuMonitorTestNew optional greeting
qemuMonitorTest: Make check for monitor command match optional
tests: Introduce qemucapabilitiestest
.gitignore | 1 +
src/qemu/qemu_capabilities.c | 144 +-
src/qemu/qemu_capabilities.h | 3 +
tests/Makefile.am | 12 +-
tests/qemucapabilitiesdata/caps_default.caps | 132 ++
tests/qemucapabilitiesdata/caps_default.replies | 2519 +++++++++++++++++++++++
tests/qemucapabilitiestest.c | 231 +++
tests/qemuhotplugtest.c | 2 +-
tests/qemumonitortestutils.c | 23 +-
tests/qemumonitortestutils.h | 5 +-
10 files changed, 2994 insertions(+), 78 deletions(-)
create mode 100644 tests/qemucapabilitiesdata/caps_default.caps
create mode 100644 tests/qemucapabilitiesdata/caps_default.replies
create mode 100644 tests/qemucapabilitiestest.c
--
1.8.1.5
11 years, 2 months
[libvirt] [PATCH] Fix max stream packet size for old clients
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The libvirtd server pushes data out to clients. It does not
know what protocol version the client might have, so must be
conservative and use the old payload limits. ie send no more
than 256kb of data per packet.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
daemon/stream.c | 2 +-
src/rpc/virnetprotocol.x | 7 +++++++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/daemon/stream.c b/daemon/stream.c
index 87dfaf5..9e36e8a 100644
--- a/daemon/stream.c
+++ b/daemon/stream.c
@@ -708,7 +708,7 @@ daemonStreamHandleRead(virNetServerClientPtr client,
daemonClientStream *stream)
{
char *buffer;
- size_t bufferLen = VIR_NET_MESSAGE_PAYLOAD_MAX;
+ size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
int ret;
VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",
diff --git a/src/rpc/virnetprotocol.x b/src/rpc/virnetprotocol.x
index 131e40b..1eae7cb 100644
--- a/src/rpc/virnetprotocol.x
+++ b/src/rpc/virnetprotocol.x
@@ -50,6 +50,13 @@
*/
const VIR_NET_MESSAGE_INITIAL = 65536;
+/*
+ * Until we enlarged the message buffers, this was the max
+ * payload size. We need to remember this for compat with
+ * old clients.
+ */
+const VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX = 262144;
+
/* Maximum total message size (serialised). */
const VIR_NET_MESSAGE_MAX = 16777216;
--
1.8.3.1
11 years, 2 months
Re: [libvirt] [PATCH 1/6] kvm: Add KVM_GET_EMULATED_CPUID
by Eduardo Habkost
On Tue, Sep 24, 2013 at 01:04:14PM +0300, Gleb Natapov wrote:
> On Tue, Sep 24, 2013 at 11:57:00AM +0200, Borislav Petkov wrote:
> > On Mon, September 23, 2013 6:28 pm, Eduardo Habkost wrote:
> > > On Sun, Sep 22, 2013 at 04:44:50PM +0200, Borislav Petkov wrote:
> > >> From: Borislav Petkov <bp(a)suse.de>
> > >>
> > >> Add a kvm ioctl which states which system functionality kvm emulates.
> > >> The format used is that of CPUID and we return the corresponding CPUID
> > >> bits set for which we do emulate functionality.
> > >
> > > Let me check if I understood the purpose of the new ioctl correctly: the
> > > only reason for GET_EMULATED_CPUID to exist is to allow userspace to
> > > differentiate features that are native or that are emulated efficiently
> > > (GET_SUPPORTED_CPUID) and features that are emulated not very
> > > efficiently (GET_EMULATED_CPUID)?
> >
> > Not only that - emulated features are not reported in CPUID so they
> > can be enabled only when specifically and explicitly requested, i.e.
> > "+movbe". Basically, you want to emulate that feature for the guest but
> > only for this specific guest - the others shouldn't see it.
Then we may have a problem: some CPU models already have "movbe"
included (e.g. Haswell), and patch 6/6 will make "-cpu Haswell" get
movbe enabled even if it is being emulated.
So if we really want to avoid enabling emulated features by mistake, we
may need a new CPU flag in addition to "enforce" to tell QEMU that it is
OK to enable emulated features (maybe "-cpu ...,emulate"?).
> >
> > > If that's the case, how do we decide how efficient emulation should be,
> > > to deserve inclusion in GET_SUPPORTED_CPUID? I am guessing that the
> > > criterion will be: if enabling it doesn't risk making performance worse,
> > > it can get in GET_SUPPORTED_CPUID.
> >
> > Well, in the MOVBE case, supported means, the host can execute this
> > instruction natively. Now, you guys say you can emulate x2apic very
> > efficiently and I'm guessing emulating x2apic doesn't bring any
> > emulation overhead, thus SUPPORTED_CPUID.
> x2apic emulation has nothing to do with x2apic in a host. It is emulated
> same way no matter if host has it or not. x2apic is not really cpu
> feature, but apic one and apic is fully emulated by KVM anyway.
But my question still stands: suppose we had x2apic emulation
implemented but for some reason it was painfully slow, we wouldn't want
to enable it by mistake. In this case, it would end up on EMULATED_CPUID
and not on SUPPORTED_CPUID, right?
>
> >
> > But for single instructions or group of instructions, the distinction
> > should be very clear.
> >
> > At least this is how I see it but Gleb probably can comment too.
> >
> That's how I see it two. Basically you want to use movbe emulation (as
> opposite of virtualization) only if you have binary kernel that compiled
> for CPU with movbe (Borislav's use case), or you want to migrate
> temporarily from movbe enabled host to non movbe host because downtime
> is not an option. We should avoid enabling it "by mistake".
"we should avoid enabling it 'by mistake'" sounds like a good criterion
for including something on GET_EMULATED_CPUID instead of
GET_SUPPORTED_CPUID.
In that case, I believe QEMU should use GET_EMULATED_CPUID only if
explicitly requested in the configuration/command-line (that's not what
patch 6/6 does).
--
Eduardo
11 years, 2 months
[libvirt] [PATCH] LXC: workaround machined uncleaned data with containers running systemd.
by Cédric Bosdonnat
The problem is described by [0] but its effect on libvirt is that
starting a container with a full distro running systemd after having
stopped it simply fails.
The container cleanup now calls the machined Terminate function to make
sure that everything is in order for the next run.
[0]: https://bugs.freedesktop.org/show_bug.cgi?id=68370
---
src/libvirt_private.syms | 2 ++
src/lxc/lxc_process.c | 8 +++++
src/util/virsystemd.c | 80 +++++++++++++++++++++++++++++++++++++++++-------
src/util/virsystemd.h | 8 +++++
tests/virsystemdtest.c | 28 +++++++++++++++++
6 files changed, 117 insertions(+), 12 deletions(-)
2nd version:
* Removed the Makefile hack and added symbols to libvirt_private.syms instead
* Added virSystemdMakeMachineName to factorize some code in Make and Terminate
machine systemd functions.
* Added tests for TerminateMachine and TerminateContainer cases.
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 48e4b04..4bc4d69 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1947,8 +1947,10 @@ virSysinfoSetup;
# util/virsystemd.h
virSystemdCreateMachine;
+virSystemdMakeMachineName;
virSystemdMakeScopeName;
virSystemdMakeSliceName;
+virSystemdTerminateMachine;
# util/virthread.h
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 4835bd5..f92c613 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -50,6 +50,7 @@
#include "virstring.h"
#include "viratomic.h"
#include "virprocess.h"
+#include "virsystemd.h"
#define VIR_FROM_THIS VIR_FROM_LXC
@@ -210,6 +211,13 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
virCgroupFree(&priv->cgroup);
}
+ /* Get machined to terminate the machine as it may not have cleaned it
+ * properly. See https://bugs.freedesktop.org/show_bug.cgi?id=68370 for
+ * the bug we are working around here.
+ */
+ virSystemdTerminateMachine(vm->def->name, "lxc", true);
+
+
/* now that we know it's stopped call the hook if present */
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
char *xml = virDomainDefFormat(vm->def, 0);
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index e72b7f0..1ba37cc 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -116,6 +116,27 @@ char *virSystemdMakeSliceName(const char *partition)
return virBufferContentAndReset(&buf);
}
+char *virSystemdMakeMachineName(const char *name,
+ const char *drivername,
+ bool privileged)
+{
+ char *machinename = NULL;
+ char *username = NULL;
+ if (privileged) {
+ if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
+ goto cleanup;
+ } else {
+ if (!(username = virGetUserName(geteuid())))
+ goto cleanup;
+ if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
+ goto cleanup;
+ }
+
+cleanup:
+ VIR_FREE(username);
+
+ return machinename;
+}
/**
* virSystemdCreateMachine:
@@ -142,7 +163,6 @@ int virSystemdCreateMachine(const char *name,
DBusConnection *conn;
char *machinename = NULL;
char *creatorname = NULL;
- char *username = NULL;
char *slicename = NULL;
ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
@@ -152,15 +172,8 @@ int virSystemdCreateMachine(const char *name,
conn = virDBusGetSystemBus();
ret = -1;
- if (privileged) {
- if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
- goto cleanup;
- } else {
- if (!(username = virGetUserName(geteuid())))
- goto cleanup;
- if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
- goto cleanup;
- }
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
+ goto cleanup;
if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0)
goto cleanup;
@@ -236,9 +249,54 @@ int virSystemdCreateMachine(const char *name,
ret = 0;
cleanup:
- VIR_FREE(username);
VIR_FREE(creatorname);
VIR_FREE(machinename);
VIR_FREE(slicename);
return ret;
}
+
+int virSystemdTerminateMachine(const char *name,
+ const char *drivername,
+ bool privileged)
+{
+ int ret;
+ DBusConnection *conn;
+ char *machinename = NULL;
+
+ ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
+ if (ret < 0)
+ return ret;
+
+ conn = virDBusGetSystemBus();
+
+ ret = -1;
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
+ goto cleanup;
+
+ /*
+ * The systemd DBus API we're invoking has the
+ * following signature
+ *
+ * TerminateMachine(in s name);
+ *
+ * @name a host unique name for the machine. shows up
+ * in 'ps' listing & similar
+ */
+
+ VIR_DEBUG("Attempting to terminate machine via systemd");
+ if (virDBusCallMethod(conn,
+ NULL,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "TerminateMachine",
+ "s",
+ machinename) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(machinename);
+ return ret;
+}
diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
index 414ae5a..d9845e1 100644
--- a/src/util/virsystemd.h
+++ b/src/util/virsystemd.h
@@ -29,6 +29,10 @@ char *virSystemdMakeScopeName(const char *name,
const char *slicename);
char *virSystemdMakeSliceName(const char *partition);
+char *virSystemdMakeMachineName(const char *name,
+ const char *drivername,
+ bool privileged);
+
int virSystemdCreateMachine(const char *name,
const char *drivername,
bool privileged,
@@ -38,4 +42,8 @@ int virSystemdCreateMachine(const char *name,
bool iscontainer,
const char *partition);
+int virSystemdTerminateMachine(const char *name,
+ const char *drivername,
+ bool privileged);
+
#endif /* __VIR_SYSTEMD_H__ */
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index e68b3ac..e6efebf 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -54,6 +54,18 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
return 0;
}
+static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED)
+{
+ if (virSystemdTerminateMachine("demo",
+ "lxc",
+ true) < 0) {
+ fprintf(stderr, "%s", "Failed to terminate LXC machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
{
unsigned char uuid[VIR_UUID_BUFLEN] = {
@@ -77,6 +89,18 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
return 0;
}
+static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED)
+{
+ if (virSystemdTerminateMachine("demo",
+ "qemu",
+ false) < 0) {
+ fprintf(stderr, "%s", "Failed to terminate KVM machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
{
unsigned char uuid[VIR_UUID_BUFLEN] = {
@@ -184,8 +208,12 @@ mymain(void)
if (virtTestRun("Test create container ", 1, testCreateContainer, NULL) < 0)
ret = -1;
+ if (virtTestRun("Test terminate container ", 1, testTerminateContainer, NULL) < 0)
+ ret = -1;
if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
ret = -1;
+ if (virtTestRun("Test terminate machine ", 1, testTerminateMachine, NULL) < 0)
+ ret = -1;
if (virtTestRun("Test create no systemd ", 1, testCreateNoSystemd, NULL) < 0)
ret = -1;
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
--
1.8.4
11 years, 2 months
[libvirt] [PATCH v2] virsh-domain: Free dom before return false in cmdDump
by Hongwei Bi
---
tools/virsh-domain.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 8538125..fa012d1 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4488,7 +4488,7 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
return false;
if (vshCommandOptStringReq(ctl, cmd, "file", &to) < 0)
- return false;
+ goto cleanup;
if (vshCommandOptBool(cmd, "verbose"))
verbose = true;
--
1.7.1
11 years, 2 months
[libvirt] [PATCH v2] virsh-volume: Add missing check when calling virStreamNew
by Hongwei Bi
Check return value of virStreamNew when called by
cmdVolUpload and cmdVolDownload.
---
tools/virsh-volume.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-volume.c b/tools/virsh-volume.c
index 7dab532..0a66a6c 100644
--- a/tools/virsh-volume.c
+++ b/tools/virsh-volume.c
@@ -665,7 +665,11 @@ cmdVolUpload(vshControl *ctl, const vshCmd *cmd)
goto cleanup;
}
- st = virStreamNew(ctl->conn, 0);
+ if (!(st = virStreamNew(ctl->conn, 0))) {
+ vshError(ctl, _("cannot create a new stream"));
+ goto cleanup;
+ }
+
if (virStorageVolUpload(vol, st, offset, length, 0) < 0) {
vshError(ctl, _("cannot upload to volume %s"), name);
goto cleanup;
@@ -775,7 +779,11 @@ cmdVolDownload(vshControl *ctl, const vshCmd *cmd)
created = true;
}
- st = virStreamNew(ctl->conn, 0);
+ if (!(st = virStreamNew(ctl->conn, 0))) {
+ vshError(ctl, _("cannot create a new stream"));
+ goto cleanup;
+ }
+
if (virStorageVolDownload(vol, st, offset, length, 0) < 0) {
vshError(ctl, _("cannot download from volume %s"), name);
goto cleanup;
--
1.7.1
11 years, 2 months
[libvirt] [PATCH v3 0/2] Libvirt Wireshark dissector
by Yuto KAWAMURA(kawamuray)
From: "Yuto KAWAMURA(kawamuray)" <kawamuray.dadada(a)gmail.com>
Changes from version2:
* Remove moduleinfo.h
* Stop accessing internal XDR struct and just use free()
Introduce Wireshark dissector plugin which adds support to Wireshark
for dissecting libvirt RPC protocol.
This feature was presented by Michal Privoznik year before last[1].
But it did only support dissecting packet headers.
This time I enhanced that dissector to support dissecting packet
payload. Furthermore, I provide code generator of dissector. So you
can get fresh build of dissector from libvirt RPC specification file
at any version you like.
[1] http://www.redhat.com/archives/libvir-list/2011-October/msg00301.html
Yuto KAWAMURA(kawamuray) (2):
Introduce Libvirt Wireshark dissector
Add sample output of Wireshark dissector
Makefile.am | 3 +-
cfg.mk | 8 +-
configure.ac | 72 +-
tools/wireshark/Makefile.am | 29 +
tools/wireshark/README.md | 31 +
tools/wireshark/samples/libvirt-sample.pdml | 206 ++++++
tools/wireshark/src/.gitignore | 4 +
tools/wireshark/src/Makefile.am | 42 ++
tools/wireshark/src/packet-libvirt.c | 512 ++++++++++++++
tools/wireshark/src/packet-libvirt.h | 128 ++++
tools/wireshark/util/genxdrstub.pl | 1009 +++++++++++++++++++++++++++
tools/wireshark/util/make-dissector-reg | 198 ++++++
12 files changed, 2236 insertions(+), 6 deletions(-)
create mode 100644 tools/wireshark/Makefile.am
create mode 100644 tools/wireshark/README.md
create mode 100644 tools/wireshark/samples/libvirt-sample.pdml
create mode 100644 tools/wireshark/src/.gitignore
create mode 100644 tools/wireshark/src/Makefile.am
create mode 100644 tools/wireshark/src/packet-libvirt.c
create mode 100644 tools/wireshark/src/packet-libvirt.h
create mode 100755 tools/wireshark/util/genxdrstub.pl
create mode 100755 tools/wireshark/util/make-dissector-reg
--
1.8.1.5
11 years, 2 months
[libvirt] [PATCH] virfile: safezero: align mmap offset to page size
by Oskari Saarenmaa
mmap's offset must be aligned to page size or mapping will fail.
mmap-based safezero is only used if posix_fallocate isn't available.
Signed-off-by: Oskari Saarenmaa <os(a)ohmu.fi>
---
src/util/virfile.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 20ca89f..16f8101 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1038,9 +1038,16 @@ safezero(int fd, off_t offset, off_t len)
int
safezero(int fd, off_t offset, off_t len)
{
+ static long pagemask = 0;
+ off_t map_skip;
int r;
char *buf;
+ /* align offset and length, rounding offset down and length up */
+ if (pagemask == 0)
+ pagemask = ~(sysconf(_SC_PAGESIZE) - 1);
+ map_skip = offset - (offset & pagemask);
+
/* memset wants the mmap'ed file to be present on disk so create a
* sparse file
*/
@@ -1048,12 +1055,13 @@ safezero(int fd, off_t offset, off_t len)
if (r < 0)
return -1;
- buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
+ buf = mmap(NULL, len + map_skip, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, offset - map_skip);
if (buf == MAP_FAILED)
return -1;
- memset(buf, 0, len);
- munmap(buf, len);
+ memset(buf + map_skip, 0, len);
+ munmap(buf, len + map_skip);
return 0;
}
--
1.8.3.1
11 years, 2 months
[libvirt] [PATCH] qemu_migrate: Fix assign the same port when migrating concurrently
by Wangyufei (A)
>From 6c2de34432db674072231ad66c9e8a0a600ede8a Mon Sep 17 00:00:00 2001
From: WangYufei <james.wangyufei(a)huawei.com>
Date: Mon, 30 Sep 2013 11:48:43 +0800
Subject: [PATCH] qemu_migrate: Fix assign the same port when migrating concurrently
When we migrate vms concurrently, there's a chance that libvirtd on destination assign the same port for different migrations, which will lead to migration failed during migration prepare phase on destination. So we use virPortAllocator here to solve the problem.
Signed-off-by: WangYufei <james.wangyufei(a)huawei.com>
---
src/qemu/qemu_command.h | 3 +++
src/qemu/qemu_conf.h | 6 +++---
src/qemu/qemu_driver.c | 6 ++++++
src/qemu/qemu_migration.c | 17 ++++++++++-------
4 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 2e2acfb..3277ba4 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -51,6 +51,9 @@
# define QEMU_WEBSOCKET_PORT_MIN 5700
# define QEMU_WEBSOCKET_PORT_MAX 65535
+# define QEMU_MIGRATION_PORT_MIN 49152
+# define QEMU_MIGRATION_PORT_MAX 49215
+
typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks;
typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr;
struct _qemuBuildCommandLineCallbacks {
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index da29a2a..3176085 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -221,6 +221,9 @@ struct _virQEMUDriver {
/* Immutable pointer, self-locking APIs */
virPortAllocatorPtr webSocketPorts;
+ /* Immutable pointer, self-locking APIs */
+ virPortAllocatorPtr migrationPorts;
+
/* Immutable pointer, lockless APIs*/
virSysinfoDefPtr hostsysinfo;
@@ -242,9 +245,6 @@ struct _qemuDomainCmdlineDef {
char **env_value;
};
-/* Port numbers used for KVM migration. */
-# define QEMUD_MIGRATION_FIRST_PORT 49152
-# define QEMUD_MIGRATION_NUM_PORTS 64
void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e8bc04d..9437b5a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -688,6 +688,11 @@ qemuStateInitialize(bool privileged,
cfg->webSocketPortMax)) == NULL)
goto error;
+ if ((qemu_driver->migrationPorts =
+ virPortAllocatorNew(QEMU_MIGRATION_PORT_MIN,
+ QEMU_MIGRATION_PORT_MAX)) == NULL)
+ goto error;
+
if (qemuSecurityInit(qemu_driver) < 0)
goto error;
@@ -994,6 +999,7 @@ qemuStateCleanup(void) {
virObjectUnref(qemu_driver->domains);
virObjectUnref(qemu_driver->remotePorts);
virObjectUnref(qemu_driver->webSocketPorts);
+ virObjectUnref(qemu_driver->migrationPorts);
virObjectUnref(qemu_driver->xmlopt);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 3a1aab7..82d90bf 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2493,7 +2493,6 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
const char *origname,
unsigned long flags)
{
- static int port = 0;
int this_port;
char *hostname = NULL;
const char *p;
@@ -2521,8 +2520,9 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
* to be a correct hostname which refers to the target machine).
*/
if (uri_in == NULL) {
- this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
- if (port == QEMUD_MIGRATION_NUM_PORTS) port = 0;
+ if (virPortAllocatorAcquire(driver->migrationPorts,
+ (unsigned short *)&this_port) < 0)
+ goto cleanup;
/* Get hostname */
if ((hostname = virGetHostname()) == NULL)
@@ -2578,9 +2578,9 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
if (uri->port == 0) {
/* Generate a port */
- this_port = QEMUD_MIGRATION_FIRST_PORT + port++;
- if (port == QEMUD_MIGRATION_NUM_PORTS)
- port = 0;
+ if (virPortAllocatorAcquire(driver->migrationPorts,
+ (unsigned short *)&this_port) < 0)
+ goto cleanup;
/* Caller frees */
if (virAsprintf(uri_out, "%s:%d", uri_in, this_port) < 0)
@@ -2600,8 +2600,11 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
cleanup:
virURIFree(uri);
VIR_FREE(hostname);
- if (ret != 0)
+ if (ret != 0) {
VIR_FREE(*uri_out);
+ virPortAllocatorRelease(driver->migrationPorts,
+ (unsigned short)this_port);
+ }
return ret;
}
--
1.7.3.1.msysgit.0
Best Regards,
-WangYufei
11 years, 2 months