[libvirt] [libvirt-glib] Turn GVirStream into a GIOStream
by Marc-André Lureau
Allows to read async from a stream with GVirInputStream.
This is modelled after GSocket.
---
libvirt-gobject/Makefile.am | 2 +
libvirt-gobject/libvirt-gobject-connection.c | 2 +-
libvirt-gobject/libvirt-gobject-input-stream.c | 239 ++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-input-stream.h | 68 +++++++
libvirt-gobject/libvirt-gobject-stream.c | 130 +++++++++++++-
libvirt-gobject/libvirt-gobject-stream.h | 10 +-
6 files changed, 443 insertions(+), 8 deletions(-)
create mode 100644 libvirt-gobject/libvirt-gobject-input-stream.c
create mode 100644 libvirt-gobject/libvirt-gobject-input-stream.h
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am
index 8147db2..7013675 100644
--- a/libvirt-gobject/Makefile.am
+++ b/libvirt-gobject/Makefile.am
@@ -40,6 +40,8 @@ libvirt_gobject_1_0_la_HEADERS = \
libvirt_gobject_1_0_la_SOURCES = \
$(libvirt_gobject_1_0_la_HEADERS) \
libvirt-gobject-enums.c \
+ libvirt-gobject-input-stream.c \
+ libvirt-gobject-input-stream.h \
$(GOBJECT_SOURCE_FILES)
libvirt_gobject_1_0_la_CFLAGS = \
-DDATADIR="\"$(datadir)\"" \
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index 5fc0a9e..95cd878 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -1151,7 +1151,7 @@ GVirStream *gvir_connection_get_stream(GVirConnection *self,
klass = GVIR_CONNECTION_GET_CLASS(self);
g_return_val_if_fail(klass->stream_new, NULL);
- virStreamPtr st = virStreamNew(self->priv->conn, flags);
+ virStreamPtr st = virStreamNew(self->priv->conn, flags | VIR_STREAM_NONBLOCK);
return klass->stream_new(self, st);
}
diff --git a/libvirt-gobject/libvirt-gobject-input-stream.c b/libvirt-gobject/libvirt-gobject-input-stream.c
new file mode 100644
index 0000000..a76d670
--- /dev/null
+++ b/libvirt-gobject/libvirt-gobject-input-stream.c
@@ -0,0 +1,239 @@
+/*
+ * libvirt-gobject-input-stream.h: libvirt gobject integration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Daniel P. Berrange <berrange(a)redhat.com>
+ * Marc-André Lureau <marcandre.lureau(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include <libvirt/virterror.h>
+#include <string.h>
+
+#include "libvirt-glib/libvirt-glib.h"
+#include "libvirt-gobject/libvirt-gobject.h"
+#include "libvirt-gobject-input-stream.h"
+
+extern gboolean debugFlag;
+
+#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0)
+
+#define gvir_input_stream_get_type _gvir_input_stream_get_type
+G_DEFINE_TYPE(GVirInputStream, gvir_input_stream, G_TYPE_INPUT_STREAM);
+
+enum
+{
+ PROP_0,
+ PROP_STREAM
+};
+
+struct _GVirInputStreamPrivate
+{
+ GVirStream *stream;
+
+ /* pending operation metadata */
+ GSimpleAsyncResult *result;
+ GCancellable *cancellable;
+ gpointer buffer;
+ gsize count;
+};
+
+static void gvir_input_stream_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GVirInputStream *stream = GVIR_INPUT_STREAM(object);
+
+ switch (prop_id) {
+ case PROP_STREAM:
+ g_value_set_object(value, stream->priv->stream);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void gvir_input_stream_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GVirInputStream *stream = GVIR_INPUT_STREAM(object);
+
+ switch (prop_id) {
+ case PROP_STREAM:
+ stream->priv->stream = g_value_dup_object(value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void gvir_input_stream_finalize(GObject *object)
+{
+ GVirInputStream *stream = GVIR_INPUT_STREAM(object);
+
+ if (stream->priv->stream)
+ g_object_unref(stream->priv->stream);
+
+ if (G_OBJECT_CLASS(gvir_input_stream_parent_class)->finalize)
+ (*G_OBJECT_CLASS(gvir_input_stream_parent_class)->finalize)(object);
+}
+
+static void
+gvir_input_stream_read_ready (G_GNUC_UNUSED virStreamPtr st,
+ int events, void *opaque)
+{
+ GVirInputStream *stream = GVIR_INPUT_STREAM(opaque);
+ GVirInputStreamPrivate *priv = stream->priv;
+ GSimpleAsyncResult *simple;
+ GError *error = NULL;
+ gssize result;
+
+ g_return_if_fail(events & VIR_STREAM_EVENT_READABLE);
+
+ result = gvir_stream_receive(priv->stream, priv->buffer, priv->count,
+ priv->cancellable, &error);
+
+ if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
+ g_warn_if_reached();
+ return;
+ }
+
+ simple = stream->priv->result;
+ stream->priv->result = NULL;
+
+ if (result >= 0)
+ g_simple_async_result_set_op_res_gssize(simple, result);
+
+ if (error)
+ g_simple_async_result_take_error(simple, error);
+
+ if (priv->cancellable) {
+ g_object_unref(stream->priv->cancellable);
+ priv->cancellable = NULL;
+ }
+
+ g_simple_async_result_complete(simple);
+ g_object_unref(simple);
+
+ return;
+}
+
+static void gvir_input_stream_read_async(GInputStream *stream,
+ void *buffer,
+ gsize count,
+ G_GNUC_UNUSED int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GVirInputStream *input_stream = GVIR_INPUT_STREAM(stream);
+ virStreamPtr handle;
+
+ g_return_if_fail(GVIR_IS_INPUT_STREAM(stream));
+ g_return_if_fail(input_stream->priv->result == NULL);
+
+ g_object_get(input_stream->priv->stream, "handle", &handle, NULL);
+
+ if (virStreamEventAddCallback(handle, VIR_STREAM_EVENT_READABLE,
+ gvir_input_stream_read_ready, stream, NULL) < 0) {
+ g_simple_async_report_error_in_idle(G_OBJECT(stream),
+ callback,
+ user_data,
+ G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Couldn't add event callback %s",
+ G_STRFUNC);
+ goto end;
+ }
+
+ input_stream->priv->result =
+ g_simple_async_result_new(G_OBJECT(stream), callback, user_data,
+ gvir_input_stream_read_async);
+ if (cancellable)
+ g_object_ref(cancellable);
+ input_stream->priv->cancellable = cancellable;
+ input_stream->priv->buffer = buffer;
+ input_stream->priv->count = count;
+
+end:
+ virStreamFree(handle);
+}
+
+
+static gssize gvir_input_stream_read_finish(GInputStream *stream,
+ GAsyncResult *result,
+ G_GNUC_UNUSED GError **error)
+{
+ GVirInputStream *input_stream = GVIR_INPUT_STREAM(stream);
+ GSimpleAsyncResult *simple;
+ virStreamPtr handle;
+ gssize count;
+
+ g_return_val_if_fail(GVIR_IS_INPUT_STREAM(stream), -1);
+ g_object_get(input_stream->priv->stream, "handle", &handle, NULL);
+
+ simple = G_SIMPLE_ASYNC_RESULT(result);
+
+ g_warn_if_fail(g_simple_async_result_get_source_tag(simple) == gvir_input_stream_read_async);
+
+ count = g_simple_async_result_get_op_res_gssize(simple);
+
+ virStreamEventRemoveCallback(handle);
+ virStreamFree(handle);
+
+ return count;
+}
+
+
+static void gvir_input_stream_class_init(GVirInputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ GInputStreamClass *ginputstream_class = G_INPUT_STREAM_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GVirInputStreamPrivate));
+
+ gobject_class->finalize = gvir_input_stream_finalize;
+ gobject_class->get_property = gvir_input_stream_get_property;
+ gobject_class->set_property = gvir_input_stream_set_property;
+
+ ginputstream_class->read_fn = NULL;
+ ginputstream_class->read_async = gvir_input_stream_read_async;
+ ginputstream_class->read_finish = gvir_input_stream_read_finish;
+
+ g_object_class_install_property(gobject_class, PROP_STREAM,
+ g_param_spec_object("stream",
+ "stream",
+ "GVirStream",
+ GVIR_TYPE_STREAM, G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+static void gvir_input_stream_init(GVirInputStream *stream)
+{
+ stream->priv = G_TYPE_INSTANCE_GET_PRIVATE(stream, GVIR_TYPE_INPUT_STREAM, GVirInputStreamPrivate);
+}
+
+GVirInputStream* _gvir_input_stream_new(GVirStream *stream)
+{
+ return GVIR_INPUT_STREAM(g_object_new(GVIR_TYPE_INPUT_STREAM, "stream", stream, NULL));
+}
diff --git a/libvirt-gobject/libvirt-gobject-input-stream.h b/libvirt-gobject/libvirt-gobject-input-stream.h
new file mode 100644
index 0000000..e8002b9
--- /dev/null
+++ b/libvirt-gobject/libvirt-gobject-input-stream.h
@@ -0,0 +1,68 @@
+/*
+ * libvirt-gobject-input-stream.h: libvirt gobject integration
+ *
+ * Copyright (C) 2011 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors: Daniel P. Berrange <berrange(a)redhat.com>
+ * Marc-André Lureau <marcandre.lureau(a)redhat.com>
+ */
+
+#if !defined(__LIBVIRT_GOBJECT_H__) && !defined(LIBVIRT_GOBJECT_BUILD)
+#error "Only <libvirt-gobject/libvirt-gobject.h> can be included directly."
+#endif
+
+#ifndef __LIBVIRT_GOBJECT_INPUT_STREAM_H__
+#define __LIBVIRT_GOBJECT_INPUT_STREAM_H__
+
+#include <gio/gio.h>
+#include "libvirt-gobject-stream.h"
+
+G_BEGIN_DECLS
+
+#define GVIR_TYPE_INPUT_STREAM (_gvir_input_stream_get_type ())
+#define GVIR_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ GVIR_TYPE_INPUT_STREAM, GVirInputStream))
+#define GVIR_INPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ GVIR_TYPE_INPUT_STREAM, GVirInputStreamClass))
+#define GVIR_IS_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ GVIR_TYPE_INPUT_STREAM))
+#define GVIR_IS_INPUT_STREAM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ GVIR_TYPE_INPUT_STREAM))
+#define GVIR_INPUT_STREAM_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ GVIR_TYPE_INPUT_STREAM, GVirInputStreamClass))
+
+typedef struct _GVirInputStreamPrivate GVirInputStreamPrivate;
+typedef struct _GVirInputStreamClass GVirInputStreamClass;
+typedef struct _GVirInputStream GVirInputStream;
+
+struct _GVirInputStreamClass
+{
+ GInputStreamClass parent_class;
+};
+
+struct _GVirInputStream
+{
+ GInputStream parent_instance;
+ GVirInputStreamPrivate *priv;
+};
+
+GType _gvir_input_stream_get_type (void) G_GNUC_CONST;
+GVirInputStream * _gvir_input_stream_new (GVirStream *stream);
+
+G_END_DECLS
+
+#endif /* __LIBVIRT_GOBJECT_INPUT_STREAM_H__ */
diff --git a/libvirt-gobject/libvirt-gobject-stream.c b/libvirt-gobject/libvirt-gobject-stream.c
index 519d733..88e3a40 100644
--- a/libvirt-gobject/libvirt-gobject-stream.c
+++ b/libvirt-gobject/libvirt-gobject-stream.c
@@ -30,6 +30,8 @@
#include "libvirt-glib/libvirt-glib.h"
#include "libvirt-gobject/libvirt-gobject.h"
+#include "libvirt-gobject/libvirt-gobject-input-stream.h"
+
extern gboolean debugFlag;
#define DEBUG(fmt, ...) do { if (G_UNLIKELY(debugFlag)) g_debug(fmt, ## __VA_ARGS__); } while (0)
@@ -39,10 +41,12 @@ extern gboolean debugFlag;
struct _GVirStreamPrivate
{
- virStreamPtr handle;
+ virStreamPtr handle;
+ GInputStream *input_stream;
+ gboolean in_dispose;
};
-G_DEFINE_TYPE(GVirStream, gvir_stream, G_TYPE_OBJECT);
+G_DEFINE_TYPE(GVirStream, gvir_stream, G_TYPE_IO_STREAM);
enum {
@@ -60,6 +64,71 @@ gvir_stream_error_quark(void)
return g_quark_from_static_string("vir-g-stream");
}
+
+static GInputStream* gvir_stream_get_input_stream(GIOStream *io_stream)
+{
+ GVirStream *self = GVIR_STREAM(io_stream);
+
+ if (self->priv->input_stream == NULL)
+ self->priv->input_stream = (GInputStream *)_gvir_input_stream_new(self);
+
+ return self->priv->input_stream;
+}
+
+
+static gboolean gvir_stream_close(GIOStream *io_stream,
+ GCancellable *cancellable, G_GNUC_UNUSED GError **error)
+{
+ GVirStream *self = GVIR_STREAM(io_stream);
+
+ if (self->priv->input_stream)
+ g_input_stream_close(self->priv->input_stream, cancellable, NULL);
+
+ if (self->priv->in_dispose)
+ return TRUE;
+
+ return TRUE; /* FIXME: really close the stream? */
+}
+
+
+static void gvir_stream_close_async(GIOStream *stream, G_GNUC_UNUSED int io_priority,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ GIOStreamClass *class;
+ GError *error;
+
+ class = G_IO_STREAM_GET_CLASS(stream);
+
+ /* close is not blocked, just do it! */
+ error = NULL;
+ if (class->close_fn &&
+ !class->close_fn(stream, cancellable, &error)) {
+ g_simple_async_report_take_gerror_in_idle(G_OBJECT (stream),
+ callback, user_data,
+ error);
+ return;
+ }
+
+ res = g_simple_async_result_new(G_OBJECT (stream),
+ callback,
+ user_data,
+ gvir_stream_close_async);
+ g_simple_async_result_complete_in_idle(res);
+ g_object_unref (res);
+}
+
+
+static gboolean
+gvir_stream_close_finish(G_GNUC_UNUSED GIOStream *stream,
+ G_GNUC_UNUSED GAsyncResult *result,
+ G_GNUC_UNUSED GError **error)
+{
+ return TRUE;
+}
+
+
static void gvir_stream_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -107,6 +176,9 @@ static void gvir_stream_finalize(GObject *object)
DEBUG("Finalize GVirStream=%p", self);
+ if (self->priv->input_stream)
+ g_object_unref(self->priv->input_stream);
+
if (priv->handle) {
if (virStreamFinish(priv->handle) < 0)
g_critical("cannot finish stream");
@@ -120,12 +192,18 @@ static void gvir_stream_finalize(GObject *object)
static void gvir_stream_class_init(GVirStreamClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ GIOStreamClass *stream_class = G_IO_STREAM_CLASS(klass);
object_class->finalize = gvir_stream_finalize;
object_class->get_property = gvir_stream_get_property;
object_class->set_property = gvir_stream_set_property;
+ stream_class->get_input_stream = gvir_stream_get_input_stream;
+ stream_class->close_fn = gvir_stream_close;
+ stream_class->close_async = gvir_stream_close_async;
+ stream_class->close_finish = gvir_stream_close_finish;
+
g_object_class_install_property(object_class,
PROP_HANDLE,
g_param_spec_boxed("handle",
@@ -170,6 +248,50 @@ GType gvir_stream_handle_get_type(void)
return handle_type;
}
+/**
+ * gvir_stream_receive:
+ * @stream: the stream
+ * @buffer: a buffer to read data into (which should be at least @size
+ * bytes long).
+ * @size: the number of bytes you want to read from the stream
+ * @cancellable: (allow-none): a %GCancellable or %NULL
+ * @error: #GError for error reporting, or %NULL to ignore.
+ *
+ * Receive data (up to @size bytes) from a stream.
+ * On error -1 is returned and @error is set accordingly.
+ *
+ * gvir_stream_receive() can return any number of bytes, up to
+ * @size. If more than @size bytes have been received, the additional
+ * data will be returned in future calls to gvir_stream_receive().
+ *
+ * If there is no data available, a %G_IO_ERROR_WOULD_BLOCK error will be
+ * returned.
+ *
+ * Returns: Number of bytes read, or 0 if the end of stream reached,
+ * or -1 on error.
+ */
+gssize gvir_stream_receive(GVirStream *self, gchar *buffer, gsize size,
+ GCancellable *cancellable, GError **error)
+{
+ int got;
+
+ g_return_val_if_fail(GVIR_IS_STREAM(self), -1);
+ g_return_val_if_fail(buffer != NULL, -1);
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return -1;
+
+ got = virStreamRecv(self->priv->handle, buffer, size);
+
+ if (got == -2) { /* blocking */
+ g_set_error(error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, NULL);
+ } else if (got < 0) {
+ g_set_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+ "Got virStreamRecv error in %s", G_STRFUNC);
+ }
+
+ return got;
+}
struct stream_sink_helper {
GVirStream *self;
@@ -197,7 +319,7 @@ stream_sink(virStreamPtr st G_GNUC_UNUSED,
* requested data sink. This is simply a convenient alternative
* to virStreamRecv, for apps that do blocking-I/o.
*/
-gint
+gssize
gvir_stream_receive_all(GVirStream *self, GVirStreamSinkFunc func, gpointer user_data, GError **err)
{
struct stream_sink_helper helper = {
diff --git a/libvirt-gobject/libvirt-gobject-stream.h b/libvirt-gobject/libvirt-gobject-stream.h
index 5181e24..35526db 100644
--- a/libvirt-gobject/libvirt-gobject-stream.h
+++ b/libvirt-gobject/libvirt-gobject-stream.h
@@ -28,6 +28,9 @@
#ifndef __LIBVIRT_GOBJECT_STREAM_H__
#define __LIBVIRT_GOBJECT_STREAM_H__
+#include <glib-object.h>
+#include <gio/gio.h>
+
G_BEGIN_DECLS
#define GVIR_TYPE_STREAM (gvir_stream_get_type ())
@@ -45,7 +48,7 @@ typedef struct _GVirStreamClass GVirStreamClass;
struct _GVirStream
{
- GObject parent;
+ GIOStream parent_instance;
GVirStreamPrivate *priv;
@@ -54,7 +57,7 @@ struct _GVirStream
struct _GVirStreamClass
{
- GObjectClass parent_class;
+ GIOStreamClass parent_class;
gpointer padding[20];
};
@@ -76,7 +79,8 @@ typedef gint (* GVirStreamSinkFunc) (GVirStream *stream,
GType gvir_stream_get_type(void);
GType gvir_stream_handle_get_type(void);
-gint gvir_stream_receive_all(GVirStream *stream, GVirStreamSinkFunc func, gpointer user_data, GError **err);
+gssize gvir_stream_receive_all(GVirStream *stream, GVirStreamSinkFunc func, gpointer user_data, GError **err);
+gssize gvir_stream_receive(GVirStream *stream, gchar *buffer, gsize size, GCancellable *cancellable, GError **error);
G_END_DECLS
--
1.7.6.2
13 years, 6 months
[libvirt] [libvirt-glib] Remove vir- prefix from signals
by Christophe Fergeau
gobject signals are generally not namespaced this way, removing
this prefix makes things look a bit nicer.
---
libvirt-gobject/libvirt-gobject-connection.c | 50 +++++++++++++-------------
libvirt-gobject/libvirt-gobject-domain.c | 10 +++---
libvirt-gobject/libvirt-gobject-manager.c | 8 ++--
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-connection.c b/libvirt-gobject/libvirt-gobject-connection.c
index 4832908..8813e96 100644
--- a/libvirt-gobject/libvirt-gobject-connection.c
+++ b/libvirt-gobject/libvirt-gobject-connection.c
@@ -170,7 +170,7 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
- signals[VIR_CONNECTION_OPENED] = g_signal_new("vir-connection-opened",
+ signals[VIR_CONNECTION_OPENED] = g_signal_new("connection-opened",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirConnectionClass, vir_connection_opened),
@@ -179,7 +179,7 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)
G_TYPE_NONE,
0);
- signals[VIR_CONNECTION_CLOSED] = g_signal_new("vir-connection-closed",
+ signals[VIR_CONNECTION_CLOSED] = g_signal_new("connection-closed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirConnectionClass, vir_connection_closed),
@@ -188,7 +188,7 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)
G_TYPE_NONE,
0);
- signals[VIR_DOMAIN_ADDED] = g_signal_new("vir-domain-added",
+ signals[VIR_DOMAIN_ADDED] = g_signal_new("domain-added",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirConnectionClass, vir_domain_added),
@@ -198,7 +198,7 @@ static void gvir_connection_class_init(GVirConnectionClass *klass)
1,
G_TYPE_OBJECT);
- signals[VIR_DOMAIN_REMOVED] = g_signal_new("vir-domain-removed",
+ signals[VIR_DOMAIN_REMOVED] = g_signal_new("domain-removed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirConnectionClass, vir_domain_removed),
@@ -282,7 +282,7 @@ static int domain_event_cb(virConnectPtr conn G_GNUC_UNUSED,
if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED)
g_signal_emit(gconn, signals[VIR_DOMAIN_ADDED], 0, gdom);
else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED)
- g_signal_emit_by_name(gdom, "vir-updated");
+ g_signal_emit_by_name(gdom, "updated");
else
g_warn_if_reached();
break;
@@ -301,60 +301,60 @@ static int domain_event_cb(virConnectPtr conn G_GNUC_UNUSED,
case VIR_DOMAIN_EVENT_STARTED:
if (detail == VIR_DOMAIN_EVENT_STARTED_BOOTED)
- g_signal_emit_by_name(gdom, "vir-started::booted");
+ g_signal_emit_by_name(gdom, "started::booted");
else if (detail == VIR_DOMAIN_EVENT_STARTED_MIGRATED)
- g_signal_emit_by_name(gdom, "vir-started::migrated");
+ g_signal_emit_by_name(gdom, "started::migrated");
else if (detail == VIR_DOMAIN_EVENT_STARTED_RESTORED)
- g_signal_emit_by_name(gdom, "vir-started::restored");
+ g_signal_emit_by_name(gdom, "started::restored");
else if (detail == VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT)
- g_signal_emit_by_name(gdom, "vir-started::from-snapshot");
+ g_signal_emit_by_name(gdom, "started::from-snapshot");
else
g_warn_if_reached();
break;
case VIR_DOMAIN_EVENT_SUSPENDED:
if (detail == VIR_DOMAIN_EVENT_SUSPENDED_PAUSED)
- g_signal_emit_by_name(gdom, "vir-suspended::paused");
+ g_signal_emit_by_name(gdom, "suspended::paused");
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED)
- g_signal_emit_by_name(gdom, "vir-suspended::migrated");
+ g_signal_emit_by_name(gdom, "suspended::migrated");
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_IOERROR)
- g_signal_emit_by_name(gdom, "vir-suspended::ioerror");
+ g_signal_emit_by_name(gdom, "suspended::ioerror");
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG)
- g_signal_emit_by_name(gdom, "vir-suspended::watchdog");
+ g_signal_emit_by_name(gdom, "suspended::watchdog");
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_RESTORED)
- g_signal_emit_by_name(gdom, "vir-suspended::restored");
+ g_signal_emit_by_name(gdom, "suspended::restored");
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT)
- g_signal_emit_by_name(gdom, "vir-suspended::from-snapshot");
+ g_signal_emit_by_name(gdom, "suspended::from-snapshot");
else
g_warn_if_reached();
break;
case VIR_DOMAIN_EVENT_RESUMED:
if (detail == VIR_DOMAIN_EVENT_RESUMED_UNPAUSED)
- g_signal_emit_by_name(gdom, "vir-resumed::unpaused");
+ g_signal_emit_by_name(gdom, "resumed::unpaused");
else if (detail == VIR_DOMAIN_EVENT_RESUMED_MIGRATED)
- g_signal_emit_by_name(gdom, "vir-resumed::migrated");
+ g_signal_emit_by_name(gdom, "resumed::migrated");
else if (detail == VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT)
- g_signal_emit_by_name(gdom, "vir-resumed::from-snapshot");
+ g_signal_emit_by_name(gdom, "resumed::from-snapshot");
else
g_warn_if_reached();
break;
case VIR_DOMAIN_EVENT_STOPPED:
if (detail == VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN)
- g_signal_emit_by_name(gdom, "vir-stopped::shutdown");
+ g_signal_emit_by_name(gdom, "stopped::shutdown");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_DESTROYED)
- g_signal_emit_by_name(gdom, "vir-stopped::destroyed");
+ g_signal_emit_by_name(gdom, "stopped::destroyed");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_CRASHED)
- g_signal_emit_by_name(gdom, "vir-stopped::crashed");
+ g_signal_emit_by_name(gdom, "stopped::crashed");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_MIGRATED)
- g_signal_emit_by_name(gdom, "vir-stopped::migrated");
+ g_signal_emit_by_name(gdom, "stopped::migrated");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_SAVED)
- g_signal_emit_by_name(gdom, "vir-stopped::saved");
+ g_signal_emit_by_name(gdom, "stopped::saved");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_FAILED)
- g_signal_emit_by_name(gdom, "vir-stopped::failed");
+ g_signal_emit_by_name(gdom, "stopped::failed");
else if (detail == VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT)
- g_signal_emit_by_name(gdom, "vir-stopped::from-snapshot");
+ g_signal_emit_by_name(gdom, "stopped::from-snapshot");
else
g_warn_if_reached();
break;
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 2a5c9fd..70d8d6d 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -159,7 +159,7 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
- signals[VIR_STARTED] = g_signal_new("vir-started",
+ signals[VIR_STARTED] = g_signal_new("started",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
@@ -169,7 +169,7 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_TYPE_NONE,
1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
- signals[VIR_SUSPENDED] = g_signal_new("vir-suspended",
+ signals[VIR_SUSPENDED] = g_signal_new("suspended",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
@@ -179,7 +179,7 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_TYPE_NONE,
1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
- signals[VIR_RESUMED] = g_signal_new("vir-resumed",
+ signals[VIR_RESUMED] = g_signal_new("resumed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
@@ -189,7 +189,7 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_TYPE_NONE,
1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
- signals[VIR_STOPPED] = g_signal_new("vir-stopped",
+ signals[VIR_STOPPED] = g_signal_new("stopped",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
@@ -199,7 +199,7 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_TYPE_NONE,
1, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
- signals[VIR_UPDATED] = g_signal_new("vir-updated",
+ signals[VIR_UPDATED] = g_signal_new("updated",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
G_STRUCT_OFFSET(GVirDomainClass, vir_domain_updated),
diff --git a/libvirt-gobject/libvirt-gobject-manager.c b/libvirt-gobject/libvirt-gobject-manager.c
index 36167be..ae3e4a1 100644
--- a/libvirt-gobject/libvirt-gobject-manager.c
+++ b/libvirt-gobject/libvirt-gobject-manager.c
@@ -88,7 +88,7 @@ static void gvir_manager_class_init(GVirManagerClass *klass)
object_class->finalize = gvir_manager_finalize;
- g_signal_new("vir-connection-added",
+ g_signal_new("connection-added",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirManagerClass, vir_connection_added),
@@ -97,7 +97,7 @@ static void gvir_manager_class_init(GVirManagerClass *klass)
G_TYPE_NONE,
1,
GVIR_TYPE_CONNECTION);
- g_signal_new("vir-connection-removed",
+ g_signal_new("connection-removed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(GVirManagerClass, vir_connection_removed),
@@ -145,7 +145,7 @@ void gvir_manager_add_connection(GVirManager *man,
/* Hold extra reference while emitting signal */
g_object_ref(conn);
g_mutex_unlock(priv->lock);
- g_signal_emit_by_name(man, "vir-connection-added", conn);
+ g_signal_emit_by_name(man, "connection-added", conn);
g_object_unref(conn);
}
@@ -158,7 +158,7 @@ void gvir_manager_remove_connection(GVirManager *man,
priv->connections = g_list_remove(priv->connections, conn);
g_mutex_unlock(priv->lock);
- g_signal_emit_by_name(man, "vir-connection-removed", conn);
+ g_signal_emit_by_name(man, "connection-removed", conn);
g_object_unref(conn);
}
--
1.7.6.4
13 years, 6 months
[libvirt] [PATCH] build: fix 'make dist' error
by Wen Congyang
When I run 'make dist', I receive the following error messages:
make[1]: Entering directory `/home/wency/source/libvirt/src'
GEN remote/remote_protocol.h
GEN remote/remote_protocol.c
GEN remote/qemu_protocol.h
GEN remote/qemu_protocol.c
GEN remote/qemu_client_bodies.h
CC libvirt_driver_remote_la-remote_protocol.lo
In file included from ./remote/remote_protocol.h:16,
from ./remote/remote_protocol.c:7:
./internal.h:249:23: error: probes.h: No such file or directory
make[1]: *** [libvirt_driver_remote_la-remote_protocol.lo] Error 1
make[1]: Leaving directory `/home/wency/source/libvirt/src'
make: *** [distdir] Error 1
The reason is that we use probes.h before generating it.
---
src/Makefile.am | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 302d395..510e5ef 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -189,6 +189,11 @@ REMOTE_DRIVER_GENERATED = \
$(srcdir)/remote/qemu_protocol.h \
$(srcdir)/remote/qemu_client_bodies.h
+# The remote RPC driver needs probes.h
+if WITH_DTRACE
+REMOTE_DRIVER_GENERATED += $(srcdir)/probes.h
+endif
+
REMOTE_PROTOCOL = $(srcdir)/remote/remote_protocol.x
QEMU_PROTOCOL = $(srcdir)/remote/qemu_protocol.x
REMOTE_DRIVER_PROTOCOL = $(REMOTE_PROTOCOL) $(QEMU_PROTOCOL)
--
1.7.1
13 years, 6 months
[libvirt] [PATCH] qemu: Get the dev from activePciHostdevs list before reattachment
by Osier Yang
BZ# https://bugzilla.redhat.com/show_bug.cgi?id=736214
The problem is caused by the original info of domain's PCI dev is
maintained by qemu_driver->activePciHostdevs list, (E.g. dev->reprobe,
which stands for whether need to reprobe driver for the dev when do
reattachment). The fields (dev->reprobe, dev->unbind_from_stub, and
dev->remove_slot) are initialized properly when preparing the PCI
device for managed attachment. However, when do reattachment, it
construct a complete new "pciDevice" without honoring the original
dev info, and thus the dev won't get the original driver or can get
other problem.
This patch is to fix the problem by get the dev from list
driver->activePciHostdevs if it's in the list, though it's unlikely
the dev to be reattached is not in the list, as any PCI dev is added
to the list when do preparation (qemuPrepareHostdevPCIDevices),
the patch doesn't completely desert the old design so the device
can be reattached even if it's not in list driver->activePciHostdevs.
--
v1 patch to fix this problem is:
http://www.redhat.com/archives/libvir-list/2011-September/msg01101.html
But the patch title is complete different, so I don't send this and
a v2.
---
src/qemu/qemu_hostdev.c | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 6f77717..73cadc5 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -262,6 +262,7 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
int nhostdevs)
{
pciDeviceList *pcidevs;
+ pciDeviceList *pci_list = NULL;
int i;
if (!(pcidevs = qemuGetPciHostDeviceList(hostdevs, nhostdevs))) {
@@ -272,12 +273,23 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
return;
}
+ if (!(pci_list = pciDeviceListNew()))
+ return;
+
/* Again 3 loops; mark all devices as inactive before reset
* them and reset all the devices before re-attach */
-
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
- pciDeviceListDel(driver->activePciHostdevs, dev);
+ pciDevice *pci = NULL;
+ pci = pciDeviceListSteal(driver->activePciHostdevs, dev);
+
+ if (pci) {
+ pciDeviceListDel(pcidevs, dev);
+ if (pciDeviceListAdd(pci_list, pci) < 0) {
+ pciFreeDevice(pci);
+ goto cleanup;
+ }
+ }
}
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
@@ -290,11 +302,18 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
}
}
+ for (i = 0; i < pciDeviceListCount(pci_list); i++) {
+ pciDevice *dev = pciDeviceListGet(pci_list, i);
+ qemuReattachPciDevice(dev, driver);
+ }
+
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
qemuReattachPciDevice(dev, driver);
}
+cleanup:
+ pciDeviceListFree(pci_list);
pciDeviceListFree(pcidevs);
}
--
1.7.6
13 years, 6 months
[libvirt] [PATCH] Add missing strdup return value check
by Roopa Prabhu
From: Roopa Prabhu <roprabhu(a)cisco.com>
Check strdup return value and fail if error
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
---
src/util/pci.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/util/pci.c b/src/util/pci.c
index 2bbb90c..df4e6c8 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -2018,7 +2018,13 @@ pciDeviceNetName(char *device_link_sysfs_path, char **netname)
/* Assume a single directory entry */
*netname = strdup(entry->d_name);
- ret = 0;
+ if (!*netname) {
+ virReportOOMError();
+ ret = -1;
+ }
+ else {
+ ret = 0;
+ }
break;
}
13 years, 6 months
[libvirt] [RFC PATCH 0/3] Guest NUMA topology support - v0
by Bharata B Rao
Hi,
I discussed the possibilities of adding NUMA topology XML specification
support for guests here some time back. Since my latest proposal
(http://permalink.gmane.org/gmane.comp.emulators.libvirt/44626)
didn't get any response, I am posting a prototype implementation
that supports specifying NUMA topology for QEMU guests.
- The implementation is based on the last proposal I listed above.
- The implementation is for QEMU only.
- The patchset has gone through extremely light testing and I have
just tested booting a 2 socket 2 core 2 thread QEMU guest.
- I haven't really bothered to cover all the corner cases and haven't
run libvirt tests after this patchset. For eg, there is no code
to validate if the CPU combination specified by <topology> and
<numa> match with each other. I plan to cover all these after we
freeze the specification itself.
Regards,
Bharata.
13 years, 6 months
[libvirt] New repositories and comments for Code Search
by Richard W.M. Jones
Enter your code repository type (SVN, CVS, Hg, Git, Archive) and URL
here:
GIT git://libvirt.org/libvirt.git
Libvirt is the virtualization API.
Comment:
You already have some random forks of libvirt.git in the archive, but
as far as I can see, not the real upstream git repo.
GIT git://git.annexia.org/git/libguestfs.git
libguestfs is a set of tools for manipulating virtual machine disk
images.
Comment:
You are already taking the Fedora packaging git archive (eg:
git://pkgs.fedoraproject.org/libguestfs.git) but those aren't the
sources, they contain the spec files and tarballs. Now, if you were
to just unpack all those tarballs, you'd have the source for 10,000s
of verified open source projects!
13 years, 6 months
[libvirt] [PATCH] macvtap: plug memory leak for 802.1Qbh
by Eric Blake
Detected by Coverity. Leak present since commit ca3b22b.
* src/util/macvtap.c (doPortProfileOp8021Qbh): Release device name.
---
getPhysfnDev allocates physfndev, but nothing freed it.
Pushing under the trivial rule.
src/util/macvtap.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 9bf7fa6..a020c90 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -983,27 +983,27 @@ doPortProfileOp8021Qbh(const char *ifname,
# ifndef IFLA_VF_PORT_MAX
(void)ifname;
(void)macaddr;
(void)virtPort;
(void)vm_uuid;
(void)virtPortOp;
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Kernel VF Port support was missing at compile time."));
rc = 1;
# else /* IFLA_VF_PORT_MAX */
- char *physfndev;
+ char *physfndev = NULL;
unsigned char hostuuid[VIR_UUID_BUFLEN];
int32_t vf;
bool nltarget_kernel = true;
int ifindex;
int vlanid = -1;
rc = getPhysfnDev(ifname, &vf, &physfndev);
if (rc)
goto err_exit;
if (ifaceGetIndex(true, physfndev, &ifindex) < 0) {
rc = 1;
goto err_exit;
@@ -1049,26 +1049,27 @@ doPortProfileOp8021Qbh(const char *ifname,
NULL,
NULL,
vf,
PORT_REQUEST_DISASSOCIATE);
break;
default:
macvtapError(VIR_ERR_INTERNAL_ERROR,
_("operation type %d not supported"), virtPortOp);
rc = 1;
}
err_exit:
+ VIR_FREE(physfndev);
# endif /* IFLA_VF_PORT_MAX */
return rc;
}
/**
* vpAssociatePortProfile
*
* @macvtap_ifname: The name of the macvtap device
* @virtPort: pointer to the object holding port profile parameters
* @vmuuid : the UUID of the virtual machine
* @vmOp : The VM operation (i.e., create, no-op)
--
1.7.4.4
13 years, 6 months
Re: [libvirt] [PATCH] Bug Fix: Fix getPhysfnDev to always allocate memory for physfndev on success
by Eric Blake
On 10/14/2011 04:12 PM, Roopa Prabhu wrote:
> From: Roopa Prabhu<roprabhu(a)cisco.com>
>
> getPhysfnDev was conditionally allocating memory for physfndev on success.
> Recently added unconditional free in the caller of getPhysfnDev
> can result in a crash. So fix getPhysfnDev to unconditionally allocate
> memory for physfndev on success
>
> Signed-off-by: Roopa Prabhu<roprabhu(a)cisco.com>
> Acked-by: Eric Blake<eblake(a)redhat.com>
> ---
> src/util/macvtap.c | 6 +++++-
> 1 files changed, 5 insertions(+), 1 deletions(-)
Already pushed.
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years, 6 months
[libvirt] [PATCH] Clarify semantics of virDomainMigrate2
by Jiri Denemark
Explicitly disallow conflicts between domain name from dxml and dname.
---
src/libvirt.c | 3 +++
src/qemu/qemu_driver.c | 4 ++--
src/qemu/qemu_migration.c | 17 ++++++++++++++---
src/qemu/qemu_migration.h | 1 +
4 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index f1e6a6b..69cffc5 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -4854,6 +4854,9 @@ error:
* in accessing the underlying storage. The migration will fail
* if @dxml would cause any guest-visible changes. Pass NULL
* if no changes are needed to the XML between source and destination.
+ * @dxml cannot be used to rename the domain during migration (use
+ * @dname for that purpose). Domain name in @dxml must either match the
+ * original domain name or @dname if it was specified.
*
* Returns the new domain object if the migration was successful,
* or NULL in case of error. Note that the new domain object
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 98f4d7f..f833655 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8043,7 +8043,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
char **cookieout,
int *cookieoutlen,
unsigned long flags,
- const char *dname ATTRIBUTE_UNUSED,
+ const char *dname,
unsigned long resource ATTRIBUTE_UNUSED)
{
struct qemud_driver *driver = domain->conn->privateData;
@@ -8083,7 +8083,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
if (qemuDomainCheckEjectableMedia(driver, vm) < 0)
goto endjob;
- if (!(xml = qemuMigrationBegin(driver, vm, xmlin,
+ if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
cookieout, cookieoutlen)))
goto endjob;
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index f0a0e49..3770bb6 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -993,6 +993,7 @@ qemuDomainMigrateGraphicsRelocate(struct qemud_driver *driver,
char *qemuMigrationBegin(struct qemud_driver *driver,
virDomainObjPtr vm,
const char *xmlin,
+ const char *dname,
char **cookieout,
int *cookieoutlen)
{
@@ -1001,8 +1002,10 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
virDomainDefPtr def = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
- VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, cookieout=%p, cookieoutlen=%p",
- driver, vm, NULLSTR(xmlin), cookieout, cookieoutlen);
+ VIR_DEBUG("driver=%p, vm=%p, xmlin=%s, dname=%s,"
+ " cookieout=%p, cookieoutlen=%p",
+ driver, vm, NULLSTR(xmlin), NULLSTR(dname),
+ cookieout, cookieoutlen);
/* Only set the phase if we are inside QEMU_ASYNC_JOB_MIGRATION_OUT.
* Otherwise we will start the async job later in the perform phase losing
@@ -1028,6 +1031,14 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
+ if (STRNEQ(def->name, vm->def->name) &&
+ (!dname || STRNEQ(def->name, dname))) {
+ qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+ "target domain name doesn't match source name"
+ " nor destination name");
+ goto cleanup;
+ }
+
if (!virDomainDefCheckABIStability(vm->def, def))
goto cleanup;
@@ -2012,7 +2023,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
* bit here, because we are already running inside the context of
* a single job. */
- dom_xml = qemuMigrationBegin(driver, vm, xmlin,
+ dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname,
&cookieout, &cookieoutlen);
if (!dom_xml)
goto cleanup;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index ec70422..f806ca1 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -79,6 +79,7 @@ int qemuMigrationSetOffline(struct qemud_driver *driver,
char *qemuMigrationBegin(struct qemud_driver *driver,
virDomainObjPtr vm,
const char *xmlin,
+ const char *dname,
char **cookieout,
int *cookieoutlen);
--
1.7.7
13 years, 6 months