[libvirt] [PATCH v2 0/9] PCI hostdev refactoring
by Andrea Bolognani
Changes in v2:
* Internal functions operate on a single device, don't pass
around device lists for no reason
* Use virHostdev prefix for internal functions
* Split off style adjustments and comments updated to separate
patches
See the cover letter for v1[1] for details about the series.
Cheers.
[1] https://www.redhat.com/archives/libvir-list/2016-January/msg00835.html
Andrea Bolognani (9):
hostdev: Add virHostdevOnlyReattachPCIDevice()
hostdev: Use common reattach code to rollback prepare errors
hostdev: Use common reattach code in virHostdevPCINodeDeviceReAttach()
hostdev: Add virHostdevOnlyDetachPCIDevice()
hostdev: Use common detach code in virHostdevPCINodeDeviceDetach()
hostdev: Minor style adjustments
hostdev: Update comments
pci: Phase out virPCIDeviceReattachInit()
pci: Add debug messages when unbinding from stub driver
src/libvirt_private.syms | 1 -
src/util/virhostdev.c | 385 ++++++++++++++++++++++++++++++-----------------
src/util/virpci.c | 30 ++--
src/util/virpci.h | 1 -
tests/virpcitest.c | 5 +-
5 files changed, 272 insertions(+), 150 deletions(-)
--
2.5.0
8 years, 9 months
[libvirt] [PATCH 0/3] make virDomainObjGetPersistentDef return only persistent definition
by Nikolay Shirokovskiy
I want to make virDomainObjGetPersistentDef return only persistent definition
as one can infer from its name. Patches 1 and 2 clean things up to make
reasoning that this operation is possible more clear.
Nikolay Shirokovskiy (3):
domain: reuse update flags checking functions
libxl: remove check duplicates
common-impl: make virDomainObjGetPersistentDef return only persistent config
src/conf/domain_conf.c | 19 ++++-----
src/libxl/libxl_driver.c | 103 ++++-------------------------------------------
src/lxc/lxc_driver.c | 75 +++-------------------------------
3 files changed, 24 insertions(+), 173 deletions(-)
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH] libxl: support assignment from a pool of SRIOV VFs
by Chunyan Liu
Add codes to support creating domain with network defition of assigning
SRIOV VF from a pool. And fix hot plug and unplug SRIOV VF under this
kind of network defition.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
src/libxl/libxl_conf.c | 5 +++--
src/libxl/libxl_domain.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
src/libxl/libxl_driver.c | 12 ++++++++++++
tests/Makefile.am | 3 +++
4 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 6320421..f50c68a 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1260,7 +1260,8 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config)
return -1;
for (i = 0; i < nnics; i++) {
- if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+ if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
+ l_nics[i]->data.network.actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
continue;
if (libxlMakeNic(def, l_nics[i], &x_nics[nvnics]))
@@ -1278,7 +1279,7 @@ libxlMakeNicList(virDomainDefPtr def, libxl_domain_config *d_config)
VIR_SHRINK_N(x_nics, nnics, nnics - nvnics);
d_config->nics = x_nics;
- d_config->num_nics = nnics;
+ d_config->num_nics = nvnics;
return 0;
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index cf5c9f6..9bf7a5a 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -35,6 +35,7 @@
#include "virstring.h"
#include "virtime.h"
#include "locking/domain_lock.h"
+#include "network/bridge_driver.h"
#define VIR_FROM_THIS VIR_FROM_LIBXL
@@ -314,7 +315,7 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
virDomainHostdevSubsysPCIPtr pcisrc;
if (dev->type == VIR_DOMAIN_DEVICE_NET)
- hostdev = &(dev->data.net)->data.hostdev.def;
+ hostdev = &dev->data.net->data.hostdev.def;
else
hostdev = dev->data.hostdev;
pcisrc = &hostdev->source.subsys.u.pci;
@@ -916,6 +917,48 @@ libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void *for_callback)
libxl_event_free(ctx, ev);
}
+static int
+libxlNetworkPrepareDevices(virDomainDefPtr def)
+{
+ int ret = -1;
+ size_t i;
+
+ for (i = 0; i < def->nnets; i++) {
+ virDomainNetDefPtr net = def->nets[i];
+ int actualType;
+
+ /* If appropriate, grab a physical device from the configured
+ * network's pool of devices, or resolve bridge device name
+ * to the one defined in the network definition.
+ */
+ if (networkAllocateActualDevice(def, net) < 0)
+ goto cleanup;
+
+ actualType = virDomainNetGetActualType(net);
+ if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+ net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ /* Each type='hostdev' network device must also have a
+ * corresponding entry in the hostdevs array. For netdevs
+ * that are hardcoded as type='hostdev', this is already
+ * done by the parser, but for those allocated from a
+ * network / determined at runtime, we need to do it
+ * separately.
+ */
+ virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
+ virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
+
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN;
+
+ if (virDomainHostdevInsert(def, hostdev) < 0)
+ goto cleanup;
+ }
+ }
+ ret = 0;
+ cleanup:
+ return ret;
+}
/*
* Start a domain through libxenlight.
@@ -992,6 +1035,9 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
vm, true) < 0)
goto cleanup;
+ if (libxlNetworkPrepareDevices(vm->def) < 0)
+ goto cleanup;
+
if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def,
cfg->ctx, &d_config) < 0)
goto cleanup;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 4a9134e..6aca042 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3047,6 +3047,12 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr driver,
libxl_device_pci_init(&pcidev);
+ /* For those allocated from a network pool/ determined at runtime, it's
+ * not handled by libxlDomainDeviceDefPostParse as hostdev, we need to
+ * set backend correctly.
+ */
+ pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN;
+
if (virDomainHostdevFind(vm->def, hostdev, &found) >= 0) {
virReportError(VIR_ERR_OPERATION_FAILED,
_("target pci device %.4x:%.2x:%.2x.%.1x already exists"),
@@ -3388,6 +3394,12 @@ libxlDomainDetachHostPCIDevice(libxlDriverPrivatePtr driver,
libxl_device_pci_init(&pcidev);
+ /* For those allocated from a network pool/ determined at runtime, it's
+ * not handled by libxlDomainDeviceDefPostParse as hostdev, we need to
+ * set backend correctly.
+ */
+ pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN;
+
idx = virDomainHostdevFind(vm->def, hostdev, &detach);
if (idx < 0) {
virReportError(VIR_ERR_OPERATION_FAILED,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ee16666..6a9fb19 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -526,6 +526,9 @@ endif ! WITH_XEN
if WITH_LIBXL
libxl_LDADDS = ../src/libvirt_driver_libxl_impl.la
+if WITH_NETWORK
+libxl_LDADDS += ../src/libvirt_driver_network_impl.la
+endif WITH_NETWORK
libxl_LDADDS += $(LDADDS)
xlconfigtest_SOURCES = \
--
1.8.5.6
8 years, 9 months
[libvirt] [PATCH v2 0/5] Add virtio-gpu & virgl support
by Marc-André Lureau
The following series allow using virtio-gpu and virgl if qemu support
it. Ths Spice bits are not yet in qemu 2.5, but should make it in 2.6
and I added the RFC patches that are expected to not change much.
v1->v2: addressing Ján Tomko review
- update accel2d/accel3d to be tristate and fix its usage
- use a single QEMU_CAPS_DEVICE_VIRTIO_GPU cap for -device
virtio-gpu-* & virtio-vga
- remove qemu legacy, -vga support or command line parsing
- add xml2xml tests
- squash xml2argvtests with their respecitve feature addition commits
- update libvirt version in doc
- update commit messages
Marc-André Lureau (5):
Replace support{2d,3d} with accel{2d,3d}
domain: replace bool accel{2d,3d} with a tristate
qemu: add virtio video device
qemu: add virtio-gpu virgl support
RFC qemu: add spice opengl support
docs/formatdomain.html.in | 11 +-
docs/schemas/domaincommon.rng | 6 +
src/conf/domain_conf.c | 84 +-
src/conf/domain_conf.h | 6 +-
src/qemu/qemu_capabilities.c | 12 +
src/qemu/qemu_capabilities.h | 3 +
src/qemu/qemu_command.c | 40 +-
src/vbox/vbox_common.c | 18 +-
src/vz/vz_sdk.c | 2 +-
tests/qemucapabilitiesdata/caps_1.2.2-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_1.3.1-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_1.4.2-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_1.5.3-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_1.6.0-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_2.1.1-1.replies | 22 +-
tests/qemucapabilitiesdata/caps_2.4.0-1.caps | 1 +
tests/qemucapabilitiesdata/caps_2.4.0-1.replies | 95 +-
tests/qemucapabilitiesdata/caps_2.5.0-1.caps | 168 +
tests/qemucapabilitiesdata/caps_2.5.0-1.replies | 4043 ++++++++++++++++++++
tests/qemucapabilitiestest.c | 1 +
.../qemuxml2argv-video-virtio-gpu-device.args | 23 +
.../qemuxml2argv-video-virtio-gpu-device.xml | 31 +
.../qemuxml2argv-video-virtio-gpu-spice-gl.args | 23 +
.../qemuxml2argv-video-virtio-gpu-spice-gl.xml | 36 +
.../qemuxml2argv-video-virtio-gpu-virgl.args | 23 +
.../qemuxml2argv-video-virtio-gpu-virgl.xml | 33 +
tests/qemuxml2argvtest.c | 14 +
tests/qemuxml2xmltest.c | 4 +
29 files changed, 4732 insertions(+), 99 deletions(-)
create mode 100644 tests/qemucapabilitiesdata/caps_2.5.0-1.caps
create mode 100644 tests/qemucapabilitiesdata/caps_2.5.0-1.replies
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-device.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-device.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-spice-gl.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-virgl.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-video-virtio-gpu-virgl.xml
--
2.5.0
8 years, 9 months
[libvirt] Libvirtd and OSX... with QEMU
by Justin Clift
Heyas,
Interestingly on OSX, starting libvirtd (1.3.1) indicates it can see
the installed QEMU. However, it crashes out shortly afterwards with
a weird error:
2016-01-17 22:02:17.159+0000: 18446744073709551615: error : virEventPollRunOnce:648 : Unable to poll on file handles: Bad file descriptor
Does anyone know what that might be about, and/or how to capture more
meaningful info? :)
Regards and best wishes,
Justin Clift
8 years, 9 months
[libvirt] [PATCHv3 0/2] notify about reverting to a snapshot
by Dmitry Andreev
Reverting to snapshot may change domain configuration but
there will be no events about that.
Lack of the event become a problem for virt-manager
https://bugzilla.redhat.com/show_bug.cgi?id=1081148
This patch-set introduces new event and emits it in
qemuDomainRevertToSnapshot.
v3:
[2/2] event is emited only in the case when stopped domain
is reverted to a stopped domain.
Dmitry Andreev (2):
Introduce new VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT sub-event
qemu: emit 'defined' event after reverted to snapshot without state
changes
examples/object-events/event-test.c | 2 ++
include/libvirt/libvirt-domain.h | 1 +
src/qemu/qemu_driver.c | 8 +++++++-
tools/virsh-domain.c | 3 ++-
4 files changed, 12 insertions(+), 2 deletions(-)
--
1.8.3.1
8 years, 9 months
[libvirt] [PATCH] libvirt-guests: emit most messages to stderr
by Michael Chapman
Some of the shell functions in this script (e.g. check_guests_shutdown)
produce output that is captured and processed by other parts of the
script. Any error messages from these shell functions must go to stderr,
not stdout.
Rather than trying to determine which messages are safe for stdout and
which are not (and maintaining this safety as the script is refactored),
simplify things by emitting all messages to stderr, except for the
output from gueststatus(), rh_status() and usage().
Signed-off-by: Michael Chapman <mike(a)very.puzzling.org>
---
tools/libvirt-guests.sh.in | 94 +++++++++++++++++++++++-----------------------
1 file changed, 47 insertions(+), 47 deletions(-)
diff --git a/tools/libvirt-guests.sh.in b/tools/libvirt-guests.sh.in
index 7f74b85..80b1ec7 100644
--- a/tools/libvirt-guests.sh.in
+++ b/tools/libvirt-guests.sh.in
@@ -92,16 +92,16 @@ test_connect()
i=${CONNECT_RETRIES}
while [ $i -gt 0 ]; do
- run_virsh "$uri" connect 2>/dev/null
+ run_virsh "$uri" connect >/dev/null 2>/dev/null
if [ $? -eq 0 ]; then
return 0;
fi
sleep ${RETRIES_SLEEP}
- eval_gettext "Unable to connect to libvirt currently. Retrying .. \$i"
+ eval_gettext "Unable to connect to libvirt currently. Retrying .. \$i" >&2
i=$(($i-1))
done
- eval_gettext "Can't connect to \$uri. Skipping."
- echo
+ eval_gettext "Can't connect to \$uri. Skipping." >&2
+ echo >&2
return 1
}
@@ -163,8 +163,8 @@ start() {
[ -f "$LISTFILE" ] || { started; return 0; }
if [ "x$ON_BOOT" != xstart ]; then
- gettext "libvirt-guests is configured not to start any guests on boot"
- echo
+ gettext "libvirt-guests is configured not to start any guests on boot" >&2
+ echo >&2
rm -f "$LISTFILE"
started
return 0
@@ -187,19 +187,19 @@ start() {
done
set +f
if ! "$configured"; then
- eval_gettext "Ignoring guests on \$uri URI"; echo
+ eval_gettext "Ignoring guests on \$uri URI" >&2; echo >&2
continue
fi
test_connect "$uri" || continue
- eval_gettext "Resuming guests on \$uri URI..."; echo
+ eval_gettext "Resuming guests on \$uri URI..." >&2; echo >&2
for guest in $list; do
name=$(guest_name "$uri" "$guest")
- eval_gettext "Resuming guest \$name: "
+ eval_gettext "Resuming guest \$name: " >&2
if guest_is_on "$uri" "$guest"; then
if "$guest_running"; then
- gettext "already active"; echo
+ gettext "already active" >&2; echo >&2
else
if "$isfirst"; then
isfirst=false
@@ -208,7 +208,7 @@ start() {
fi
retval run_virsh "$uri" start $bypass "$name" \
>/dev/null && \
- gettext "done"; echo
+ gettext "done" >&2; echo >&2
if "$sync_time"; then
run_virsh "$uri" domtime --sync "$name" >/dev/null
fi
@@ -234,7 +234,7 @@ suspend_guest()
bypass=
slept=0
test "x$BYPASS_CACHE" = x0 || bypass=--bypass-cache
- printf '%s...\n' "$label"
+ printf '%s...\n' "$label" >&2
run_virsh "$uri" managedsave $bypass "$guest" >/dev/null &
virsh_pid=$!
while true; do
@@ -246,9 +246,9 @@ suspend_guest()
progress=$(run_virsh_c "$uri" domjobinfo "$guest" 2>/dev/null | \
awk '/^Data processed:/{print $3, $4}')
if [ -n "$progress" ]; then
- printf '%s%s\n' "$label" "$progress"
+ printf '%s%s\n' "$label" "$progress" >&2
else
- printf '%s%s\n' "$label" "..."
+ printf '%s%s\n' "$label" "..." >&2
fi
fi
done
@@ -264,8 +264,8 @@ shutdown_guest()
guest=$2
name=$(guest_name "$uri" "$guest")
- eval_gettext "Starting shutdown on guest: \$name"
- echo
+ eval_gettext "Starting shutdown on guest: \$name" >&2
+ echo >&2
retval run_virsh "$uri" shutdown "$guest" >/dev/null || return
timeout=$SHUTDOWN_TIMEOUT
check_timeout=false
@@ -283,24 +283,24 @@ shutdown_guest()
if $check_timeout; then
if [ $(($timeout % 5)) -eq 0 ]; then
- printf "$format" "$name" "$timeout"
+ printf "$format" "$name" "$timeout" >&2
fi
timeout=$(($timeout - 1))
else
slept=$(($slept + 1))
if [ $(($slept % 5)) -eq 0 ]; then
- printf "$format" "$name"
+ printf "$format" "$name" >&2
fi
fi
done
if guest_is_on "$uri" "$guest"; then
if "$guest_running"; then
- eval_gettext "Shutdown of guest \$name failed to complete in time."
+ eval_gettext "Shutdown of guest \$name failed to complete in time." >&2
else
- eval_gettext "Shutdown of guest \$name complete."
+ eval_gettext "Shutdown of guest \$name complete." >&2
fi
- echo
+ echo >&2
fi
}
@@ -313,8 +313,8 @@ shutdown_guest_async()
guest=$2
name=$(guest_name "$uri" "$guest")
- eval_gettext "Starting shutdown on guest: \$name"
- echo
+ eval_gettext "Starting shutdown on guest: \$name" >&2
+ echo >&2
retval run_virsh "$uri" shutdown "$guest" > /dev/null
}
@@ -337,8 +337,8 @@ check_guests_shutdown()
guests_up=
for guest in $guests; do
if ! guest_is_on "$uri" "$guest" >/dev/null 2>&1; then
- eval_gettext "Failed to determine state of guest: \$guest. Not tracking it anymore."
- echo
+ eval_gettext "Failed to determine state of guest: \$guest. Not tracking it anymore." >&2
+ echo >&2
continue
fi
if "$guest_running"; then
@@ -363,8 +363,8 @@ print_guests_shutdown()
esac
name=$(guest_name "$uri" "$guest")
- eval_gettext "Shutdown of guest \$name complete."
- echo
+ eval_gettext "Shutdown of guest \$name complete." >&2
+ echo >&2
done
}
@@ -404,18 +404,18 @@ shutdown_guests_parallel()
if $check_timeout; then
if [ $(($timeout % 5)) -eq 0 ]; then
- printf "$format" $(($guestcount + $shutdowncount)) "$timeout"
+ printf "$format" $(($guestcount + $shutdowncount)) "$timeout" >&2
fi
timeout=$(($timeout - 1))
if [ $timeout -le 0 ]; then
- eval_gettext "Timeout expired while shutting down domains"; echo
+ eval_gettext "Timeout expired while shutting down domains" >&2; echo >&2
RETVAL=1
return
fi
else
slept=$(($slept + 1))
if [ $(($slept % 5)) -eq 0 ]; then
- printf "$format" $(($guestcount + $shutdowncount))
+ printf "$format" $(($guestcount + $shutdowncount)) >&2
fi
fi
@@ -435,8 +435,8 @@ stop() {
if [ "x$ON_SHUTDOWN" = xshutdown ]; then
suspending=false
if [ $SHUTDOWN_TIMEOUT -lt 0 ]; then
- gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0"
- echo
+ gettext "SHUTDOWN_TIMEOUT must be equal or greater than 0" >&2
+ echo >&2
RETVAL=6
return
fi
@@ -449,21 +449,21 @@ stop() {
test_connect "$uri" || continue
- eval_gettext "Running guests on \$uri URI: "
+ eval_gettext "Running guests on \$uri URI: " >&2
list=$(list_guests "$uri")
if [ $? -eq 0 ]; then
empty=true
for uuid in $list; do
- "$empty" || printf ", "
- printf %s "$(guest_name "$uri" "$uuid")"
+ "$empty" || printf ", " >&2
+ printf %s "$(guest_name "$uri" "$uuid")" >&2
empty=false
done
if "$empty"; then
- gettext "no running guests."
+ gettext "no running guests." >&2
fi
- echo
+ echo >&2
fi
if "$suspending"; then
@@ -472,26 +472,26 @@ stop() {
empty=true
for uuid in $transient; do
if "$empty"; then
- eval_gettext "Not suspending transient guests on URI: \$uri: "
+ eval_gettext "Not suspending transient guests on URI: \$uri: " >&2
empty=false
else
- printf ", "
+ printf ", " >&2
fi
- printf %s "$(guest_name "$uri" "$uuid")"
+ printf %s "$(guest_name "$uri" "$uuid")" >&2
done
- echo
+ echo >&2
# reload domain list to contain only persistent guests
list=$(list_guests "$uri" "--persistent")
if [ $? -ne 0 ]; then
- eval_gettext "Failed to list persistent guests on \$uri"
- echo
+ eval_gettext "Failed to list persistent guests on \$uri" >&2
+ echo >&2
RETVAL=1
set +f
return
fi
else
- gettext "Failed to list transient guests"
- echo
+ gettext "Failed to list transient guests" >&2
+ echo >&2
RETVAL=1
set +f
return
@@ -507,9 +507,9 @@ stop() {
if [ -s "$LISTFILE" ]; then
while read uri list; do
if "$suspending"; then
- eval_gettext "Suspending guests on \$uri URI..."; echo
+ eval_gettext "Suspending guests on \$uri URI..." >&2; echo >&2
else
- eval_gettext "Shutting down guests on \$uri URI..."; echo
+ eval_gettext "Shutting down guests on \$uri URI..." >&2; echo >&2
fi
if [ "$PARALLEL_SHUTDOWN" -gt 1 ] &&
--
2.4.3
8 years, 9 months
[libvirt] ARM KVM GICv3 Support
by Christoffer Dall
Hi all,
I'm trying to figure out what the correct solution for libvirt support
for ARM KVM guests with GICv3 is.
The challenge is that QEMU's virt machine model defaults to GICv2 unless
you specify an additional "-machine gic-version=host" parameter to QEMU,
in which case your VM gets the same GIC version as your host.
Now, I'm told that this is inconvenient for libvirt, because it
typically does not pass any -machine options, is that correct?
Further, there are two additional complications: First, some guest
images may not include GICv3 support. For Linux, this is relatively old
kernels (prior to v3.17), but other guests may only support GICv2.
Second, some hardware platforms only support GICv2 guests, some only
support GICv3 guests, and some support both GICv2 and GICv3 guests
(those hosts with a GICv3 with the backwards compatibility support).
It is unclear to me how libvirt users will relate to these constraints.
For example, in an OpenStack deployment, will it somehow be easy to tell
which nodes support which GIC version such that administrators can
choose compatible VM images, or how does that work?
The end goal here is to determine if we need to add any functionality to
QEMU to better support libvirt, and what kind of features/glue need to
be added to libvirt for this to work.
Much thanks for any feedback!
-Christoffer
8 years, 9 months
[libvirt] [PATCH] migration: add option to set target ndb server port
by Nikolay Shirokovskiy
Current libvirt + qemu pair lacks secure migrations in case of
VMs with non-shared disks. The only option to migrate securely
natively is to use tunneled mode and some kind of secure
destination URI. But tunelled mode does not support non-shared
disks.
The other way to make migration secure is to organize a tunnel
by external means. This is possible in case of shared disks
migration thru use of proper combination of destination URI,
migration URI and VIR_MIGRATE_PARAM_LISTEN_ADDRESS migration
param. But again this is not possible in case of non shared disks
migration as we have no option to control target nbd server port.
But fixing this much more simplier that supporting non-shared
disks in tunneled mode.
So this patch adds option to set target ndb port.
Finally all qemu migration connections will be secured AFAIK but
even in this case this patch could be convinient if one wants
all migration traffic be put in a single connection.
---
include/libvirt/libvirt-domain.h | 10 +++
src/qemu/qemu_driver.c | 25 ++++---
src/qemu/qemu_migration.c | 138 +++++++++++++++++++++++++++------------
src/qemu/qemu_migration.h | 3 +
tools/virsh-domain.c | 12 ++++
tools/virsh.pod | 5 +-
6 files changed, 141 insertions(+), 52 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index d26faa5..e577f26 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -757,6 +757,16 @@ typedef enum {
*/
# define VIR_MIGRATE_PARAM_MIGRATE_DISKS "migrate_disks"
+/**
+ * VIR_MIGRATE_PARAM_NBD_PORT:
+ *
+ * virDomainMigrate* params field: port that destination nbd server should use
+ * for incoming disks migration. Type is VIR_TYPED_PARAM_INT. If set to 0 or
+ * omitted, libvirt will choose a suitable default. At the moment this is only
+ * supported by the QEMU driver.
+ */
+# define VIR_MIGRATE_PARAM_NBD_PORT "nbd_port"
+
/* Domain migration. */
virDomainPtr virDomainMigrate (virDomainPtr domain, virConnectPtr dconn,
unsigned long flags, const char *dname,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8ccf68b..4d00ba4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12082,7 +12082,7 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
ret = qemuMigrationPrepareDirect(driver, dconn,
NULL, 0, NULL, NULL, /* No cookies */
uri_in, uri_out,
- &def, origname, NULL, 0, NULL, flags);
+ &def, origname, NULL, 0, NULL, 0, flags);
cleanup:
VIR_FREE(origname);
@@ -12135,7 +12135,7 @@ qemuDomainMigratePerform(virDomainPtr dom,
* Consume any cookie we were able to decode though
*/
ret = qemuMigrationPerform(driver, dom->conn, vm,
- NULL, dconnuri, uri, NULL, NULL, 0, NULL,
+ NULL, dconnuri, uri, NULL, NULL, 0, NULL, 0,
cookie, cookielen,
NULL, NULL, /* No output cookies in v2 */
flags, dname, resource, false);
@@ -12308,7 +12308,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn,
cookiein, cookieinlen,
cookieout, cookieoutlen,
uri_in, uri_out,
- &def, origname, NULL, 0, NULL, flags);
+ &def, origname, NULL, 0, NULL, 0, flags);
cleanup:
VIR_FREE(origname);
@@ -12334,6 +12334,7 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
const char *dname = NULL;
const char *uri_in = NULL;
const char *listenAddress = cfg->migrationAddress;
+ int nbdPort = 0;
int nmigrate_disks;
const char **migrate_disks = NULL;
char *origname = NULL;
@@ -12354,7 +12355,10 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
&uri_in) < 0 ||
virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
- &listenAddress) < 0)
+ &listenAddress) < 0 ||
+ virTypedParamsGetInt(params, nparams,
+ VIR_MIGRATE_PARAM_NBD_PORT,
+ &nbdPort) < 0)
goto cleanup;
nmigrate_disks = virTypedParamsGetStringList(params, nparams,
@@ -12385,7 +12389,8 @@ qemuDomainMigratePrepare3Params(virConnectPtr dconn,
cookieout, cookieoutlen,
uri_in, uri_out,
&def, origname, listenAddress,
- nmigrate_disks, migrate_disks, flags);
+ nmigrate_disks, migrate_disks,
+ nbdPort, flags);
cleanup:
VIR_FREE(migrate_disks);
@@ -12519,7 +12524,7 @@ qemuDomainMigratePerform3(virDomainPtr dom,
}
return qemuMigrationPerform(driver, dom->conn, vm, xmlin,
- dconnuri, uri, NULL, NULL, 0, NULL,
+ dconnuri, uri, NULL, NULL, 0, NULL, 0,
cookiein, cookieinlen,
cookieout, cookieoutlen,
flags, dname, resource, true);
@@ -12546,6 +12551,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
int nmigrate_disks;
const char **migrate_disks = NULL;
unsigned long long bandwidth = 0;
+ int nbdPort;
int ret = -1;
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
@@ -12569,7 +12575,10 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
&graphicsuri) < 0 ||
virTypedParamsGetString(params, nparams,
VIR_MIGRATE_PARAM_LISTEN_ADDRESS,
- &listenAddress) < 0)
+ &listenAddress) < 0 ||
+ virTypedParamsGetInt(params, nparams,
+ VIR_MIGRATE_PARAM_NBD_PORT,
+ &nbdPort) < 0)
goto cleanup;
nmigrate_disks = virTypedParamsGetStringList(params, nparams,
@@ -12589,7 +12598,7 @@ qemuDomainMigratePerform3Params(virDomainPtr dom,
ret = qemuMigrationPerform(driver, dom->conn, vm, dom_xml,
dconnuri, uri, graphicsuri, listenAddress,
- nmigrate_disks, migrate_disks,
+ nmigrate_disks, migrate_disks, nbdPort,
cookiein, cookieinlen, cookieout, cookieoutlen,
flags, dname, bandwidth, true);
cleanup:
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 51e7125..362da0f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1709,7 +1709,8 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
virDomainObjPtr vm,
const char *listenAddr,
size_t nmigrate_disks,
- const char **migrate_disks)
+ const char **migrate_disks,
+ int nbdPort)
{
int ret = -1;
qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -1717,6 +1718,12 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
char *diskAlias = NULL;
size_t i;
+ if (nbdPort < 0 || nbdPort > USHRT_MAX) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("nbd port must be in range 0-65535"));
+ return -1;
+ }
+
for (i = 0; i < vm->def->ndisks; i++) {
virDomainDiskDefPtr disk = vm->def->disks[i];
@@ -1733,10 +1740,15 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
goto cleanup;
- if (!port &&
- ((virPortAllocatorAcquire(driver->migrationPorts, &port) < 0) ||
- (qemuMonitorNBDServerStart(priv->mon, listenAddr, port) < 0))) {
- goto exit_monitor;
+ if (port == 0) {
+ if (nbdPort)
+ port = nbdPort;
+ else
+ if (virPortAllocatorAcquire(driver->migrationPorts, &port) < 0)
+ goto exit_monitor;
+
+ if (qemuMonitorNBDServerStart(priv->mon, listenAddr, port) < 0)
+ goto exit_monitor;
}
if (qemuMonitorNBDServerAdd(priv->mon, diskAlias, true) < 0)
@@ -1750,7 +1762,8 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
cleanup:
VIR_FREE(diskAlias);
- if (ret < 0)
+ // second clause means port is autoselected
+ if (ret < 0 && nbdPort == 0)
virPortAllocatorRelease(driver->migrationPorts, port);
return ret;
@@ -2062,6 +2075,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuMigrationCookiePtr mig,
const char *host,
+ int nbdPort,
unsigned long speed,
unsigned int *migrate_flags,
size_t nmigrate_disks,
@@ -2081,6 +2095,12 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
VIR_DEBUG("Starting drive mirrors for domain %s", vm->def->name);
+ if (nbdPort != mig->nbd->port) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("target qemu does not support setting nbd port"));
+ return -1;
+ }
+
/* steal NBD port and thus prevent its propagation back to destination */
port = mig->nbd->port;
mig->nbd->port = 0;
@@ -3402,6 +3422,7 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
unsigned long flags)
{
virDomainObjPtr vm = NULL;
@@ -3601,7 +3622,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NBD_SERVER)) {
if (qemuMigrationStartNBDServer(driver, vm, incoming->address,
- nmigrate_disks, migrate_disks) < 0) {
+ nmigrate_disks, migrate_disks,
+ nbdPort) < 0) {
goto stopjob;
}
cookieFlags |= QEMU_MIGRATION_COOKIE_NBD;
@@ -3653,6 +3675,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
if (autoPort)
priv->migrationPort = port;
+ // in this case port is autoselected and we don't need to manage it anymore
+ // after cookie is baked
+ if (nbdPort != 0)
+ priv->nbdPort = 0;
ret = 0;
cleanup:
@@ -3664,7 +3690,10 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
/* priv is set right after vm is added to the list of domains
* and there is no 'goto cleanup;' in the middle of those */
VIR_FREE(priv->origname);
- virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
+ // release if port is auto selected which is not the case if
+ // it is given in parameters
+ if (nbdPort == 0)
+ virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
priv->nbdPort = 0;
qemuDomainRemoveInactive(driver, vm);
}
@@ -3721,7 +3750,7 @@ qemuMigrationPrepareTunnel(virQEMUDriverPtr driver,
ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
cookieout, cookieoutlen, def, origname,
- st, NULL, 0, false, NULL, 0, NULL, flags);
+ st, NULL, 0, false, NULL, 0, NULL, 0, flags);
return ret;
}
@@ -3763,6 +3792,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
unsigned long flags)
{
unsigned short port = 0;
@@ -3776,11 +3806,11 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, dconn=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, uri_in=%s, uri_out=%p, "
"def=%p, origname=%s, listenAddress=%s, "
- "nmigrate_disks=%zu, migrate_disks=%p, flags=%lx",
+ "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, flags=%lx",
driver, dconn, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, NULLSTR(uri_in), uri_out,
*def, origname, NULLSTR(listenAddress),
- nmigrate_disks, migrate_disks, flags);
+ nmigrate_disks, migrate_disks, nbdPort, flags);
*uri_out = NULL;
@@ -3885,7 +3915,7 @@ qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
cookieout, cookieoutlen, def, origname,
NULL, uri ? uri->scheme : "tcp",
port, autoPort, listenAddress,
- nmigrate_disks, migrate_disks, flags);
+ nmigrate_disks, migrate_disks, nbdPort, flags);
cleanup:
virURIFree(uri);
VIR_FREE(hostname);
@@ -4365,7 +4395,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
virConnectPtr dconn,
const char *graphicsuri,
size_t nmigrate_disks,
- const char **migrate_disks)
+ const char **migrate_disks,
+ int nbdPort)
{
int ret = -1;
unsigned int migrate_flags = QEMU_MONITOR_MIGRATE_BACKGROUND;
@@ -4383,11 +4414,11 @@ qemuMigrationRun(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, "
"spec=%p (dest=%d, fwd=%d), dconn=%p, graphicsuri=%s, "
- "nmigrate_disks=%zu, migrate_disks=%p",
+ "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d",
driver, vm, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, flags, resource,
spec, spec->destType, spec->fwdType, dconn,
- NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
+ NULLSTR(graphicsuri), nmigrate_disks, migrate_disks, nbdPort);
if (flags & VIR_MIGRATE_NON_SHARED_DISK) {
migrate_flags |= QEMU_MONITOR_MIGRATE_NON_SHARED_DISK;
@@ -4425,6 +4456,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
/* This will update migrate_flags on success */
if (qemuMigrationDriveMirror(driver, vm, mig,
spec->dest.host.name,
+ nbdPort,
migrate_speed,
&migrate_flags,
nmigrate_disks,
@@ -4661,7 +4693,8 @@ static int doNativeMigrate(virQEMUDriverPtr driver,
virConnectPtr dconn,
const char *graphicsuri,
size_t nmigrate_disks,
- const char **migrate_disks)
+ const char **migrate_disks,
+ int nbdPort)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
virURIPtr uribits = NULL;
@@ -4670,10 +4703,11 @@ static int doNativeMigrate(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, vm=%p, uri=%s, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, "
- "graphicsuri=%s, nmigrate_disks=%zu migrate_disks=%p",
+ "graphicsuri=%s, nmigrate_disks=%zu, migrate_disks=%p, "
+ "nbdPort=%d",
driver, vm, uri, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, flags, resource,
- NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
+ NULLSTR(graphicsuri), nmigrate_disks, migrate_disks, nbdPort);
if (!(uribits = qemuMigrationParseURI(uri, NULL)))
return -1;
@@ -4711,7 +4745,8 @@ static int doNativeMigrate(virQEMUDriverPtr driver,
ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout,
cookieoutlen, flags, resource, &spec, dconn,
- graphicsuri, nmigrate_disks, migrate_disks);
+ graphicsuri, nmigrate_disks, migrate_disks,
+ nbdPort);
if (spec.destType == MIGRATION_DEST_FD)
VIR_FORCE_CLOSE(spec.dest.fd.qemu);
@@ -4735,7 +4770,8 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
virConnectPtr dconn,
const char *graphicsuri,
size_t nmigrate_disks,
- const char **migrate_disks)
+ const char **migrate_disks,
+ int nbdPort)
{
virNetSocketPtr sock = NULL;
int ret = -1;
@@ -4745,10 +4781,12 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, vm=%p, st=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, "
- "graphicsuri=%s, nmigrate_disks=%zu, migrate_disks=%p",
+ "graphicsuri=%s, nmigrate_disks=%zu, migrate_disks=%p, "
+ "nbdPort=%d",
driver, vm, st, NULLSTR(cookiein), cookieinlen,
cookieout, cookieoutlen, flags, resource,
- NULLSTR(graphicsuri), nmigrate_disks, migrate_disks);
+ NULLSTR(graphicsuri), nmigrate_disks, migrate_disks,
+ nbdPort);
spec.fwdType = MIGRATION_FWD_STREAM;
spec.fwd.stream = st;
@@ -4772,7 +4810,8 @@ static int doTunnelMigrate(virQEMUDriverPtr driver,
ret = qemuMigrationRun(driver, vm, cookiein, cookieinlen, cookieout,
cookieoutlen, flags, resource, &spec, dconn,
- graphicsuri, nmigrate_disks, migrate_disks);
+ graphicsuri, nmigrate_disks, migrate_disks,
+ nbdPort);
cleanup:
if (spec.destType == MIGRATION_DEST_FD) {
@@ -4883,12 +4922,12 @@ static int doPeer2PeerMigrate2(virQEMUDriverPtr driver,
ret = doTunnelMigrate(driver, vm, st,
NULL, 0, NULL, NULL,
flags, resource, dconn,
- NULL, 0, NULL);
+ NULL, 0, NULL, 0);
else
ret = doNativeMigrate(driver, vm, uri_out,
cookie, cookielen,
NULL, NULL, /* No out cookie with v2 migration */
- flags, resource, dconn, NULL, 0, NULL);
+ flags, resource, dconn, NULL, 0, NULL, 0);
/* Perform failed. Make sure Finish doesn't overwrite the error */
if (ret < 0)
@@ -4952,6 +4991,7 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
unsigned long long bandwidth,
bool useParams,
unsigned long flags)
@@ -4975,11 +5015,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, "
"dname=%s, uri=%s, graphicsuri=%s, listenAddress=%s, "
- "nmigrate_disks=%zu, migrate_disks=%p, bandwidth=%llu, "
- "useParams=%d, flags=%lx",
+ "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
+ "bandwidth=%llu, useParams=%d, flags=%lx",
driver, sconn, dconn, NULLSTR(dconnuri), vm, NULLSTR(xmlin),
NULLSTR(dname), NULLSTR(uri), NULLSTR(graphicsuri),
- NULLSTR(listenAddress), nmigrate_disks, migrate_disks,
+ NULLSTR(listenAddress), nmigrate_disks, migrate_disks, nbdPort,
bandwidth, useParams, flags);
/* Unlike the virDomainMigrateVersion3 counterpart, we don't need
@@ -5029,6 +5069,11 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
VIR_MIGRATE_PARAM_MIGRATE_DISKS,
migrate_disks[i]) < 0)
goto cleanup;
+ if (nbdPort &&
+ virTypedParamsAddInt(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_NBD_PORT,
+ nbdPort) < 0)
+ goto cleanup;
}
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
@@ -5114,13 +5159,13 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
cookiein, cookieinlen,
&cookieout, &cookieoutlen,
flags, bandwidth, dconn, graphicsuri,
- nmigrate_disks, migrate_disks);
+ nmigrate_disks, migrate_disks, nbdPort);
} else {
ret = doNativeMigrate(driver, vm, uri,
cookiein, cookieinlen,
&cookieout, &cookieoutlen,
flags, bandwidth, dconn, graphicsuri,
- nmigrate_disks, migrate_disks);
+ nmigrate_disks, migrate_disks, nbdPort);
}
/* Perform failed. Make sure Finish doesn't overwrite the error */
@@ -5295,6 +5340,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
unsigned long flags,
const char *dname,
unsigned long resource,
@@ -5310,10 +5356,12 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, uri=%s, "
"graphicsuri=%s, listenAddress=%s, nmigrate_disks=%zu, "
- "migrate_disks=%p, flags=%lx, dname=%s, resource=%lu",
+ "migrate_disks=%p, nbdPort=%d, flags=%lx, dname=%s, "
+ "resource=%lu",
driver, sconn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
- nmigrate_disks, migrate_disks, flags, NULLSTR(dname), resource);
+ nmigrate_disks, migrate_disks, nbdPort, flags, NULLSTR(dname),
+ resource);
if (flags & VIR_MIGRATE_TUNNELLED && uri) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
@@ -5408,8 +5456,8 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
if (*v3proto) {
ret = doPeer2PeerMigrate3(driver, sconn, dconn, dconnuri, vm, xmlin,
dname, uri, graphicsuri, listenAddress,
- nmigrate_disks, migrate_disks, resource,
- useParams, flags);
+ nmigrate_disks, migrate_disks, nbdPort,
+ resource, useParams, flags);
} else {
ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm,
dconnuri, flags, dname, resource);
@@ -5446,6 +5494,7 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -5481,13 +5530,13 @@ qemuMigrationPerformJob(virQEMUDriverPtr driver,
if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
ret = doPeer2PeerMigrate(driver, conn, vm, xmlin,
dconnuri, uri, graphicsuri, listenAddress,
- nmigrate_disks, migrate_disks,
+ nmigrate_disks, migrate_disks, nbdPort,
flags, dname, resource, &v3proto);
} else {
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM2);
ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen,
cookieout, cookieoutlen,
- flags, resource, NULL, NULL, 0, NULL);
+ flags, resource, NULL, NULL, 0, NULL, 0);
}
if (ret < 0)
goto endjob;
@@ -5547,6 +5596,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver,
const char *graphicsuri,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -5572,7 +5622,7 @@ qemuMigrationPerformPhase(virQEMUDriverPtr driver,
ret = doNativeMigrate(driver, vm, uri, cookiein, cookieinlen,
cookieout, cookieoutlen,
flags, resource, NULL, graphicsuri,
- nmigrate_disks, migrate_disks);
+ nmigrate_disks, migrate_disks, nbdPort);
if (ret < 0) {
if (qemuMigrationRestoreDomainState(conn, vm)) {
@@ -5614,6 +5664,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
const char *cookiein,
int cookieinlen,
char **cookieout,
@@ -5625,13 +5676,14 @@ qemuMigrationPerform(virQEMUDriverPtr driver,
{
VIR_DEBUG("driver=%p, conn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
"uri=%s, graphicsuri=%s, listenAddress=%s, "
- "nmigrate_disks=%zu, migrate_disks=%p, "
+ "nmigrate_disks=%zu, migrate_disks=%p, nbdPort=%d, "
"cookiein=%s, cookieinlen=%d, cookieout=%p, cookieoutlen=%p, "
"flags=%lx, dname=%s, resource=%lu, v3proto=%d",
driver, conn, vm, NULLSTR(xmlin), NULLSTR(dconnuri),
NULLSTR(uri), NULLSTR(graphicsuri), NULLSTR(listenAddress),
- nmigrate_disks, migrate_disks, NULLSTR(cookiein), cookieinlen,
- cookieout, cookieoutlen, flags, NULLSTR(dname), resource, v3proto);
+ nmigrate_disks, migrate_disks, nbdPort,
+ NULLSTR(cookiein), cookieinlen, cookieout, cookieoutlen,
+ flags, NULLSTR(dname), resource, v3proto);
if ((flags & (VIR_MIGRATE_TUNNELLED | VIR_MIGRATE_PEER2PEER))) {
if (cookieinlen) {
@@ -5642,7 +5694,7 @@ qemuMigrationPerform(virQEMUDriverPtr driver,
return qemuMigrationPerformJob(driver, conn, vm, xmlin, dconnuri, uri,
graphicsuri, listenAddress,
- nmigrate_disks, migrate_disks,
+ nmigrate_disks, migrate_disks, nbdPort,
cookiein, cookieinlen,
cookieout, cookieoutlen,
flags, dname, resource, v3proto);
@@ -5656,14 +5708,14 @@ qemuMigrationPerform(virQEMUDriverPtr driver,
if (v3proto) {
return qemuMigrationPerformPhase(driver, conn, vm, uri,
graphicsuri,
- nmigrate_disks, migrate_disks,
+ nmigrate_disks, migrate_disks, nbdPort,
cookiein, cookieinlen,
cookieout, cookieoutlen,
flags, resource);
} else {
return qemuMigrationPerformJob(driver, conn, vm, xmlin, NULL,
uri, graphicsuri, listenAddress,
- nmigrate_disks, migrate_disks,
+ nmigrate_disks, migrate_disks, nbdPort,
cookiein, cookieinlen,
cookieout, cookieoutlen, flags,
dname, resource, v3proto);
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index 2445e13..2796361 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -51,6 +51,7 @@
VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \
VIR_MIGRATE_PARAM_GRAPHICS_URI, VIR_TYPED_PARAM_STRING, \
VIR_MIGRATE_PARAM_LISTEN_ADDRESS, VIR_TYPED_PARAM_STRING, \
+ VIR_MIGRATE_PARAM_NBD_PORT, VIR_TYPED_PARAM_INT, \
VIR_MIGRATE_PARAM_MIGRATE_DISKS, VIR_TYPED_PARAM_STRING | \
VIR_TYPED_PARAM_MULTIPLE, \
NULL
@@ -134,6 +135,7 @@ int qemuMigrationPrepareDirect(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
unsigned long flags);
int qemuMigrationPerform(virQEMUDriverPtr driver,
@@ -146,6 +148,7 @@ int qemuMigrationPerform(virQEMUDriverPtr driver,
const char *listenAddress,
size_t nmigrate_disks,
const char **migrate_disks,
+ int nbdPort,
const char *cookiein,
int cookieinlen,
char **cookieout,
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index d239ba8..54c9fd0 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9651,6 +9651,10 @@ static const vshCmdOptDef opts_migrate[] = {
.type = VSH_OT_STRING,
.help = N_("comma separated list of disks to be migrated")
},
+ {.name = "nbd-port",
+ .type = VSH_OT_INT,
+ .help = N_("port to use by target nbd server")
+ },
{.name = NULL}
};
@@ -9661,6 +9665,7 @@ doMigrate(void *opaque)
virDomainPtr dom = NULL;
const char *desturi = NULL;
const char *opt = NULL;
+ int optInt = 0;
unsigned int flags = 0;
virshCtrlData *data = opaque;
vshControl *ctl = data->ctl;
@@ -9703,6 +9708,13 @@ doMigrate(void *opaque)
VIR_MIGRATE_PARAM_LISTEN_ADDRESS, opt) < 0)
goto save_error;
+ if (vshCommandOptInt(ctl, cmd, "nbd-port", &optInt) < 0)
+ goto out;
+ if (optInt &&
+ virTypedParamsAddInt(¶ms, &nparams, &maxparams,
+ VIR_MIGRATE_PARAM_NBD_PORT, optInt) < 0)
+ goto save_error;
+
if (vshCommandOptStringReq(ctl, cmd, "dname", &opt) < 0)
goto out;
if (opt &&
diff --git a/tools/virsh.pod b/tools/virsh.pod
index e830c59..c0c4e81 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1532,7 +1532,7 @@ to the I<uri> namespace is displayed instead of being modified.
[I<--compressed>] [I<--abort-on-error>] [I<--auto-converge>]
I<domain> I<desturi> [I<migrateuri>] [I<graphicsuri>] [I<listen-address>]
[I<dname>] [I<--timeout> B<seconds>] [I<--xml> B<file>]
-[I<--migrate-disks> B<disk-list>]
+[I<--migrate-disks> B<disk-list>] [I<--nbd-port> B<port>]
Migrate domain to another host. Add I<--live> for live migration; <--p2p>
for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
@@ -1659,6 +1659,9 @@ addresses are accepted as well as hostnames (the resolving is done on
destination). Some hypervisors do not support this feature and will return an
error if this parameter is used.
+Optional I<nbd-port> sets the port that hypervisor on destination side should
+bind to for incoming nbd traffic. Currently it is supported only by qemu.
+
=item B<migrate-setmaxdowntime> I<domain> I<downtime>
Set maximum tolerable downtime for a domain which is being live-migrated to
--
1.8.3.1
8 years, 9 months
[libvirt] Found mem leak in livirt, need help to debug
by Piotr Rybicki
Hi.
There is a mem leak in libvirt, when doing external snapshot (for backup
purposes). My KVM domain uses raw storage images via libgfapi. I'm using
latest 1.2.21 libvirt (although previous versions act the same).
My bash script for snapshot backup uses series of shell commands (virsh
connect to a remote libvirt host):
* virsh domblklist KVM
* qemu-img create -f qcow2 -o backing_file=gluster(...) - precreate
backing file
* virsh snapshot-create KVM SNAP.xml (...) - create snapshot from
precreated XML snapshot file
* cp main img file
* virsh blockcommit KVM disk (...)
Backup script works fine, however libvirtd process gets bigger and
bigger each time I run this script.
Some proof of memleak:
32017 - libvirtd pid
When libvirt started:
# ps p 32017 o vsz,rss
VSZ RSS
585736 15220
When I start KVM via virsh start KVM
# ps p 32017 o vsz,rss
VSZ RSS
1327968 125956
When i start backup script, after snapshot is created (lots of mem
allocated)
# ps p 32017 o vsz,rss
VSZ RSS
3264544 537632
After backup script finished
# ps p 32017 o vsz,rss
VSZ RSS
3715920 644940
When i start backup script for a second time, after snapshot is created
# ps p 32017 o vsz,rss
VSZ RSS
5521424 1056352
And so on, until libvirt spills 'Out of memory' when connecting, ane
being really huge process.
Now, I would like to diagnose it further, to provide detailed
information about memleak. I tried to use valgrind, but unfortunatelly
I'm on Opteron 6380 platform, and valgrind doesn't support XOP quitting
witch SIGILL.
If someone could provide me with detailed information on how to get some
usefull debug info about this memleak, i'll be more than happy to do it,
and share results here.
Thanks in advance and best regards
Piotr Rybicki
8 years, 9 months