[libvirt] sending openvswitch "port db" info during libvirt migration
by Laine Stump
Someone asked on IRC the other day about sending openvswitch per-port
data (normally stored in the switch) to the destination host during a
migration. I suggested maybe this could be handled by encoding the
information into the interface's <virtualport> prior to migration, and
then writing it back out to openvswitch on the destination when the
interface was reconnected there.
I think there's a problem with that, though - they don't want to save
the port data on the source until the instant that the interface is
disconnected (since it is constantly changing), but by then the domain
XML has already long ago been formatted and sent to the destination.
So is there some other way within the confines of the current migration
protocol that this information can be sent from migration source to
destination?
12 years, 3 months
[libvirt] [PATCH] [libvirt-java] Fix Array IndexOutOfBoundsException for unknown error codes
by Claudio Bley
Hi.
I sent a few mails on friday, 6th July, via gmane.org but they haven't
made it to the list yet. As I'm a subscriber now, I'm resending them
directly. Sorry for any duplicates in advance.
I'm using libvirt-java 0.4.7 and libvirt 0.9.8.
When libvirt returns an error code which is not mapped in enum
ErrorNumber, an IndexOutOfBoundsException is thrown.
I realize that the freshly released libvirt-java 0.4.8 supports all
error codes up to libvirt 0.9.12. But that doesn't fix the problem.
Would it be feasible to add a special UNKNOWN enum value?
---
diff --git a/src/main/java/org/libvirt/Error.java b/src/main/java/org/libvirt/Error.java
index 0946030..72bc698 100644
--- a/src/main/java/org/libvirt/Error.java
+++ b/src/main/java/org/libvirt/Error.java
@@ -151,9 +151,12 @@ public class Error implements Serializable {
}
public Error(virError vError) {
- code = ErrorNumber.values()[vError.code];
- domain = ErrorDomain.values()[vError.domain];
- level = ErrorLevel.values()[vError.level];
+ if (ErrorNumber.values().length > vError.code)
+ code = ErrorNumber.values()[vError.code];
+ if (ErrorDomain.values().length > vError.domain)
+ domain = ErrorDomain.values()[vError.domain];
+ if (ErrorLevel.values().length > vError.level)
+ level = ErrorLevel.values()[vError.level];
message = vError.message;
str1 = vError.str1;
str2 = vError.str2;
---
Best regards,
Claudio.
--
AV-Test GmbH, Henricistraße 20, 04155 Leipzig, Germany
Phone: +49 341 265 310 19
Web:<http://www.av-test.org>
Eingetragen am / Registered at: Amtsgericht Stendal (HRB 114076)
Geschaeftsfuehrer (CEO): Andreas Marx, Guido Habicht, Maik Morgenstern
12 years, 3 months
[libvirt] [PATCH] qemu: Migrate at unlimited speed by default
by Jiri Denemark
Previously, qemu did not respond to monitor commands during migration if
the limit was too high. This prevented us from raising the limit
earlier. The qemu issue seems to be fixed (according to my testing) and
we may remove the 32Mb/s limit.
---
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_domain.h | 5 ++---
src/qemu/qemu_migration.c | 4 ++--
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 86f0265..a54df2f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -217,7 +217,7 @@ static void *qemuDomainObjPrivateAlloc(void)
if (!(priv->cons = virConsoleAlloc()))
goto error;
- priv->migMaxBandwidth = QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX;
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
return priv;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 9f9467d..23a5111 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -38,13 +38,12 @@
(1 << VIR_DOMAIN_VIRT_KVM) | \
(1 << VIR_DOMAIN_VIRT_XEN))
-# define QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX 32
# if ULONG_MAX == 4294967295
/* Qemu has a 64-bit limit, but we are limited by our historical choice of
* representing bandwidth in a long instead of a 64-bit int. */
-# define QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX ULONG_MAX
+# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX ULONG_MAX
# else
-# define QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024))
+# define QEMU_DOMAIN_MIG_BANDWIDTH_MAX (INT64_MAX / (1024 * 1024))
# endif
# define JOB_MASK(job) (1 << (job - 1))
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index b792456..6eddce6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -3189,8 +3189,8 @@ qemuMigrationToFile(struct qemud_driver *driver, virDomainObjPtr vm,
* Failure to change migration speed is not fatal. */
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
qemuMonitorSetMigrationSpeed(priv->mon,
- QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX);
- priv->migMaxBandwidth = QEMU_DOMAIN_FILE_MIG_BANDWIDTH_MAX;
+ QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
+ priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
qemuDomainObjExitMonitorWithDriver(driver, vm);
}
--
1.7.11.1
12 years, 3 months
[libvirt] [PATCH] examples: Update strings for event details
by Jiri Denemark
---
examples/domain-events/events-c/event-test.c | 2 +-
examples/domain-events/events-python/event-test.py | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c
index f11c7a3..347ee5a 100644
--- a/examples/domain-events/events-c/event-test.c
+++ b/examples/domain-events/events-c/event-test.c
@@ -176,7 +176,7 @@ static const char *eventDetailToString(int event, int detail) {
ret = "Migrated";
break;
case VIR_DOMAIN_EVENT_STOPPED_SAVED:
- ret = "Failed";
+ ret = "Saved";
break;
case VIR_DOMAIN_EVENT_STOPPED_FAILED:
ret = "Failed";
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 736c225..e3b6ed2 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -443,9 +443,9 @@ def detailToString(event, detail):
eventStrings = (
( "Added", "Updated" ),
( "Removed" ),
- ( "Booted", "Migrated", "Restored", "Snapshot" ),
- ( "Paused", "Migrated", "IOError", "Watchdog" ),
- ( "Unpaused", "Migrated"),
+ ( "Booted", "Migrated", "Restored", "Snapshot", "Wakeup" ),
+ ( "Paused", "Migrated", "IOError", "Watchdog", "Restored", "Snapshot" ),
+ ( "Unpaused", "Migrated", "Snapshot" ),
( "Shutdown", "Destroyed", "Crashed", "Migrated", "Saved", "Failed", "Snapshot"),
( "Finished" )
)
--
1.7.11.1
12 years, 3 months
[libvirt] [PATCH] qemu: Fixe debug message in p2p migration
by Jiri Denemark
When entering "confirm" phase, we are interested in the value of
cancelled rather then ret variable which was interesting before "finish"
phase and didn't change since then.
---
src/qemu/qemu_migration.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 74b70c7..f65c81a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2459,7 +2459,7 @@ finish:
* If cancelled, then src VM will be restarted, else
* it will be killed
*/
- VIR_DEBUG("Confirm3 %p ret=%d vm=%p", sconn, ret, vm);
+ VIR_DEBUG("Confirm3 %p cancelled=%d vm=%p", sconn, cancelled, vm);
VIR_FREE(cookiein);
cookiein = cookieout;
cookieinlen = cookieoutlen;
--
1.7.11.1
12 years, 3 months
[libvirt] [PATCH v7 0/6] file descriptor passing using fd sets
by Corey Bryant
libvirt's sVirt security driver provides SELinux MAC isolation for
Qemu guest processes and their corresponding image files. In other
words, sVirt uses SELinux to prevent a QEMU process from opening
files that do not belong to it.
sVirt provides this support by labeling guests and resources with
security labels that are stored in file system extended attributes.
Some file systems, such as NFS, do not support the extended
attribute security namespace, and therefore cannot support sVirt
isolation.
A solution to this problem is to provide fd passing support, where
libvirt opens files and passes file descriptors to QEMU. This,
along with SELinux policy to prevent QEMU from opening files, can
provide image file isolation for NFS files stored on the same NFS
mount.
This patch series adds the add-fd, remove-fd, and query-fdsets
QMP monitor commands, which allow file descriptors to be passed
via SCM_RIGHTS, and assigned to specified fd sets. This allows
fd sets to be created per file with fds having, for example,
different access rights. When QEMU needs to reopen a file with
different access rights, it can search for a matching fd in the
fd set. Fd sets also allow for easy tracking of fds per file,
helping to prevent fd leaks.
Support is also added to the block layer to allow QEMU to dup an
fd from an fdset when the filename is of the /dev/fdset/nnn format,
where nnn is the fd set ID.
No new SELinux policy is required to prevent open of NFS files
(files with type nfs_t). The virt_use_nfs boolean type simply
needs to be set to false, and open will be prevented (and dup will
be allowed). For example:
# setsebool virt_use_nfs 0
# getsebool virt_use_nfs
virt_use_nfs --> off
Corey Bryant (6):
qemu-char: Add MSG_CMSG_CLOEXEC flag to recvmsg
qapi: Introduce add-fd, remove-fd, query-fdsets
monitor: Clean up fd sets on monitor disconnect
block: Convert open calls to qemu_open
block: Convert close calls to qemu_close
block: Enable qemu_open/close to work with fd sets
block/raw-posix.c | 42 ++++-----
block/raw-win32.c | 6 +-
block/vdi.c | 5 +-
block/vmdk.c | 25 +++--
block/vpc.c | 4 +-
block/vvfat.c | 16 ++--
cutils.c | 5 +
monitor.c | 273 +++++++++++++++++++++++++++++++++++++++++++++++++++++
monitor.h | 5 +
osdep.c | 117 +++++++++++++++++++++++
qapi-schema.json | 110 +++++++++++++++++++++
qemu-char.c | 12 ++-
qemu-common.h | 2 +
qemu-tool.c | 20 ++++
qerror.c | 4 +
qerror.h | 3 +
qmp-commands.hx | 131 +++++++++++++++++++++++++
savevm.c | 4 +-
18 files changed, 730 insertions(+), 54 deletions(-)
--
1.7.10.4
12 years, 3 months
[libvirt] [libvirt-glib] Fix small typo in error message ('downlaod')
by Christophe Fergeau
---
Pushed under the trivial rule.
libvirt-gobject/libvirt-gobject-storage-vol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c
index 99ccbab..9256445 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.c
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.c
@@ -384,7 +384,7 @@ gboolean gvir_storage_vol_download(GVirStorageVol *vol,
gvir_set_error_literal(err,
GVIR_STORAGE_VOL_ERROR,
0,
- "Unable to downlaod volume storage");
+ "Unable to download volume storage");
goto cleanup;
}
--
1.7.11.2
12 years, 3 months
[libvirt] [PATCH] qemu: Refactor parsing of block device IO tuning parameters.
by Peter Krempa
This patch refactors the JSON parsing function that extracts the block
IO tuning parameters from qemu's output. The most impacting change
concerns the error message that is returned if the reply from qemu does
not contain the needed data. The data for IO parameter tuning were added
in qemu 1.1 and the previous error message was confusing.
This patch also breaks long lines and extracts a multiple time used code
pattern to a macro.
---
Old error message looks like:
# virsh blkdeviotune asdf hda
error: Unable to get block I/O throttle parameters
error: internal error cannot read total_bytes_sec
and the new:
# virsh blkdeviotune asdf hda
error: Unable to get block I/O throttle parameters
error: internal error block_io_throttle field 'total_bytes_sec' missing in qemu's output
src/qemu/qemu_monitor_json.c | 66 ++++++++++++++++-------------------------
1 files changed, 26 insertions(+), 40 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index dd6536f..3ede88d 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3648,6 +3648,16 @@ int qemuMonitorJSONOpenGraphics(qemuMonitorPtr mon,
}
+#define GET_THROTTLE_STATS(FIELD, STORE) \
+ if (virJSONValueObjectGetNumberUlong(inserted, \
+ FIELD, \
+ &reply->STORE) < 0) { \
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
+ _("block_io_throttle field '%s' missing " \
+ "in qemu's output"), \
+ #STORE); \
+ goto cleanup; \
+ }
static int
qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
const char *device,
@@ -3656,7 +3666,7 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
virJSONValuePtr io_throttle;
int ret = -1;
int i;
- int found = 0;
+ bool found = false;
io_throttle = virJSONValueObjectGet(result, "return");
@@ -3673,13 +3683,15 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
if (!temp_dev || temp_dev->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle device entry was not in expected format"));
+ _("block_io_throttle device entry "
+ "was not in expected format"));
goto cleanup;
}
- if ((current_dev = virJSONValueObjectGetString(temp_dev, "device")) == NULL) {
+ if (!(current_dev = virJSONValueObjectGetString(temp_dev, "device"))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle device entry was not in expected format"));
+ _("block_io_throttle device entry "
+ "was not in expected format"));
goto cleanup;
}
@@ -3689,49 +3701,22 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
if (STREQ(current_dev, device))
continue;
- found = 1;
+ found = true;
if ((inserted = virJSONValueObjectGet(temp_dev, "inserted")) == NULL ||
inserted->type != VIR_JSON_TYPE_OBJECT) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("block_io_throttle inserted entry was not in expected format"));
+ _("block_io_throttle inserted entry "
+ "was not in expected format"));
goto cleanup;
}
- if (virJSONValueObjectGetNumberUlong(inserted, "bps", &reply->total_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read total_bytes_sec"));
- goto cleanup;
- }
+ GET_THROTTLE_STATS("bps", total_bytes_sec);
+ GET_THROTTLE_STATS("bps_rd", read_bytes_sec);
+ GET_THROTTLE_STATS("bps_wr", write_bytes_sec);
+ GET_THROTTLE_STATS("iops", total_iops_sec);
+ GET_THROTTLE_STATS("iops_rd", read_iops_sec);
+ GET_THROTTLE_STATS("iops_wr", write_iops_sec);
- if (virJSONValueObjectGetNumberUlong(inserted, "bps_rd", &reply->read_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read read_bytes_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "bps_wr", &reply->write_bytes_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read write_bytes_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops", &reply->total_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read total_iops_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops_rd", &reply->read_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read read_iops_sec"));
- goto cleanup;
- }
-
- if (virJSONValueObjectGetNumberUlong(inserted, "iops_wr", &reply->write_iops_sec) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot read write_iops_sec"));
- goto cleanup;
- }
break;
}
@@ -3746,6 +3731,7 @@ qemuMonitorJSONBlockIoThrottleInfo(virJSONValuePtr result,
cleanup:
return ret;
}
+#undef GET_THROTTLE_STATS
int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
const char *device,
--
1.7.8.6
12 years, 3 months
[libvirt] [PATCH][TCK] Add new case for domain suspend/resume
by Kyla Zhang
This case tests the domain suspend and resume, and domain info
checking include state, control and os type.
---
scripts/domain/140-transient-suspend-resume.t | 91 +++++++++++++++++++++++++
1 files changed, 91 insertions(+), 0 deletions(-)
create mode 100644 scripts/domain/140-transient-suspend-resume.t
diff --git a/scripts/domain/140-transient-suspend-resume.t b/scripts/domain/140-transient-suspend-resume.t
new file mode 100644
index 0000000..a1c6f91
--- /dev/null
+++ b/scripts/domain/140-transient-suspend-resume.t
@@ -0,0 +1,91 @@
+# -*- perl -*-
+#
+# Copyright (C) 2012 Red Hat, Inc.
+# Copyright (C) 2012 Kyla Zhang <weizhan(a)redhat.com>
+#
+# This program is free software; You can redistribute it and/or modify
+# it under the GNU General Public License as published by the Free
+# Software Foundation; either version 2, or (at your option) any
+# later version
+#
+# The file "LICENSE" distributed along with this file provides full
+# details of the terms and conditions
+#
+
+=pod
+
+=head1 NAME
+
+domain/130-transient-suspend-resume.t - Transient domain suspend/resume
+
+=head1 DESCRIPTION
+
+The test case validates that it is possible to pause and resume transient
+domain without error.
+
+=cut
+
+use strict;
+use warnings;
+
+use Test::More tests => 14;
+
+use Sys::Virt::TCK;
+use Test::Exception;
+
+my $tck = Sys::Virt::TCK->new();
+my $conn = eval { $tck->setup(); };
+BAIL_OUT "failed to setup test harness: $@" if $@;
+END { $tck->cleanup if $tck; }
+
+# Create a new transient domain and check status
+my $xml = $tck->generic_domain("tck")->as_xml;
+
+diag "Creating a new transient domain";
+my $dom;
+ok_domain(sub { $dom = $conn->create_domain($xml) }, "created transient domain object");
+
+diag "Get domain os type";
+my $os_type = xpath($dom, "string(/domain/os/type)");
+is($dom->get_os_type(), $os_type, "domain os type is $os_type");
+
+diag "Check domain state and reason";
+my($state, $reason)=$dom->get_state();
+is($state, Sys::Virt::Domain::STATE_RUNNING, "domain state is running");
+is($reason, Sys::Virt::Domain::STATE_RUNNING_BOOTED, "domain is running after being booted");
+
+diag "Get domain control info";
+is($dom->get_control_info->{state}, Sys::Virt::Domain::CONTROL_OK, "domain control info is ok");
+
+# Do suspend/resume and check status
+diag "Suspend domain";
+lives_ok(sub { $dom->suspend() }, "domain has been suspended");
+
+diag "Get domain state and reason";
+($state, $reason)=$dom->get_state();
+is($state, Sys::Virt::Domain::STATE_PAUSED, "domain state is paused");
+is($reason, Sys::Virt::Domain::STATE_PAUSED_USER, "domain is paused at admin request");
+
+diag "Get domain control info";
+is($dom->get_control_info->{state}, Sys::Virt::Domain::CONTROL_OK, "domain control info is ok");
+
+diag "Resume domain";
+lives_ok( sub { $dom->resume() }, "domain has been resumed");
+
+diag "Get domain state and reason";
+($state, $reason)=$dom->get_state();
+is($state, Sys::Virt::Domain::STATE_RUNNING, "domain state is running");
+is($reason, Sys::Virt::Domain::STATE_RUNNING_UNPAUSED, "domain is running after a resume");
+
+diag "Get domain control info";
+is($dom->get_control_info->{state}, Sys::Virt::Domain::CONTROL_OK, "domain control info is ok");
+
+# Destroy domain
+diag "Destroying the transient domain";
+$dom->destroy;
+
+diag "Checking that transient domain has gone away";
+ok_error(sub { $conn->get_domain_by_name("tck") }, "NO_DOMAIN error raised from missing domain",
+ Sys::Virt::Error::ERR_NO_DOMAIN);
+
+# end
--
1.7.1
12 years, 3 months