|
Packit |
a07778 |
/*
|
|
Packit |
a07778 |
* libvirt-gobject-connection.c: libvirt glib integration
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Copyright (C) 2008 Daniel P. Berrange
|
|
Packit |
a07778 |
* Copyright (C) 2010-2011 Red Hat, Inc.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
a07778 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License as published by the Free Software Foundation; either
|
|
Packit |
a07778 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
a07778 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a07778 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a07778 |
* Lesser General Public License for more details.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a07778 |
* License along with this library. If not, see
|
|
Packit |
a07778 |
* <http://www.gnu.org/licenses/>.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <config.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <libvirt/libvirt.h>
|
|
Packit |
a07778 |
#include <string.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include <glib/gi18n-lib.h>
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#include "libvirt-glib/libvirt-glib.h"
|
|
Packit |
a07778 |
#include "libvirt-gobject/libvirt-gobject.h"
|
|
Packit |
a07778 |
#include "libvirt-gobject-compat.h"
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#define GVIR_CONNECTION_GET_PRIVATE(obj) \
|
|
Packit |
a07778 |
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_CONNECTION, GVirConnectionPrivate))
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
struct _GVirConnectionPrivate
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GMutex *lock;
|
|
Packit |
a07778 |
gchar *uri;
|
|
Packit |
a07778 |
virConnectPtr conn;
|
|
Packit |
a07778 |
gboolean read_only;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GHashTable *domains;
|
|
Packit |
a07778 |
GHashTable *pools;
|
|
Packit |
a07778 |
GHashTable *interfaces;
|
|
Packit |
a07778 |
GHashTable *networks;
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_TYPE_WITH_PRIVATE(GVirConnection, gvir_connection, G_TYPE_OBJECT);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum {
|
|
Packit |
a07778 |
PROP_0,
|
|
Packit |
a07778 |
PROP_URI,
|
|
Packit |
a07778 |
PROP_HANDLE,
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum {
|
|
Packit |
a07778 |
VIR_CONNECTION_OPENED,
|
|
Packit |
a07778 |
VIR_CONNECTION_CLOSED,
|
|
Packit |
a07778 |
VIR_DOMAIN_ADDED,
|
|
Packit |
a07778 |
VIR_DOMAIN_REMOVED,
|
|
Packit |
a07778 |
LAST_SIGNAL
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gint signals[LAST_SIGNAL];
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#define GVIR_CONNECTION_ERROR gvir_connection_error_quark()
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GQuark
|
|
Packit |
a07778 |
gvir_connection_error_quark(void)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_quark_from_static_string("gvir-connection");
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GVirNodeInfo *
|
|
Packit |
a07778 |
gvir_node_info_copy(GVirNodeInfo *info)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_slice_dup(GVirNodeInfo, info);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_node_info_free(GVirNodeInfo *info)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_slice_free(GVirNodeInfo, info);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_BOXED_TYPE(GVirNodeInfo, gvir_node_info,
|
|
Packit |
a07778 |
gvir_node_info_copy, gvir_node_info_free)
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_connection_get_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_URI:
|
|
Packit |
a07778 |
g_value_set_string(value, priv->uri);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
case PROP_HANDLE:
|
|
Packit |
a07778 |
g_value_set_boxed(value, priv->conn);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_connection_set_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
const GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_URI:
|
|
Packit |
a07778 |
g_free(priv->uri);
|
|
Packit |
a07778 |
priv->uri = g_value_dup_string(value);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_HANDLE:
|
|
Packit |
a07778 |
if (priv->conn)
|
|
Packit |
a07778 |
virConnectClose(priv->conn);
|
|
Packit |
a07778 |
priv->conn = g_value_dup_boxed(value);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_connection_finalize(GObject *object)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (gvir_connection_is_open(conn))
|
|
Packit |
a07778 |
gvir_connection_close(conn);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_free(priv->lock);
|
|
Packit |
a07778 |
g_free(priv->uri);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_OBJECT_CLASS(gvir_connection_parent_class)->finalize(object);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GVirStream* gvir_connection_stream_new(GVirConnection *self G_GNUC_UNUSED,
|
|
Packit |
a07778 |
gpointer handle)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_object_new(GVIR_TYPE_STREAM, "handle", handle, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_connection_class_init(GVirConnectionClass *klass)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gvir_event_register();
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
object_class->finalize = gvir_connection_finalize;
|
|
Packit |
a07778 |
object_class->get_property = gvir_connection_get_property;
|
|
Packit |
a07778 |
object_class->set_property = gvir_connection_set_property;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
klass->stream_new = gvir_connection_stream_new;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_URI,
|
|
Packit |
a07778 |
g_param_spec_string("uri",
|
|
Packit |
a07778 |
"URI",
|
|
Packit |
a07778 |
"The connection URI",
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
G_PARAM_READABLE |
|
|
Packit |
a07778 |
G_PARAM_WRITABLE |
|
|
Packit |
a07778 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_HANDLE,
|
|
Packit |
a07778 |
g_param_spec_boxed("handle",
|
|
Packit |
a07778 |
"Handle",
|
|
Packit |
a07778 |
"The connection handle",
|
|
Packit |
a07778 |
GVIR_TYPE_CONNECTION_HANDLE,
|
|
Packit |
a07778 |
G_PARAM_READABLE |
|
|
Packit |
a07778 |
G_PARAM_WRITABLE |
|
|
Packit |
a07778 |
G_PARAM_CONSTRUCT_ONLY |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
signals[VIR_CONNECTION_OPENED] = g_signal_new("connection-opened",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_FIRST,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirConnectionClass, connection_opened),
|
|
Packit |
a07778 |
NULL, NULL,
|
|
Packit |
a07778 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit |
a07778 |
G_TYPE_NONE,
|
|
Packit |
a07778 |
0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
signals[VIR_CONNECTION_CLOSED] = g_signal_new("connection-closed",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_FIRST,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirConnectionClass, connection_closed),
|
|
Packit |
a07778 |
NULL, NULL,
|
|
Packit |
a07778 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit |
a07778 |
G_TYPE_NONE,
|
|
Packit |
a07778 |
0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
signals[VIR_DOMAIN_ADDED] = g_signal_new("domain-added",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_FIRST,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirConnectionClass, domain_added),
|
|
Packit |
a07778 |
NULL, NULL,
|
|
Packit |
a07778 |
g_cclosure_marshal_VOID__OBJECT,
|
|
Packit |
a07778 |
G_TYPE_NONE,
|
|
Packit |
a07778 |
1,
|
|
Packit |
a07778 |
GVIR_TYPE_DOMAIN);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
signals[VIR_DOMAIN_REMOVED] = g_signal_new("domain-removed",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_FIRST,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirConnectionClass, domain_removed),
|
|
Packit |
a07778 |
NULL, NULL,
|
|
Packit |
a07778 |
g_cclosure_marshal_VOID__OBJECT,
|
|
Packit |
a07778 |
G_TYPE_NONE,
|
|
Packit |
a07778 |
1,
|
|
Packit |
a07778 |
GVIR_TYPE_DOMAIN);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_connection_init(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv = GVIR_CONNECTION_GET_PRIVATE(conn);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv->lock = g_mutex_new();
|
|
Packit |
a07778 |
priv->domains = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
priv->pools = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
priv->interfaces = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
priv->networks = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirConnection *gvir_connection_new(const char *uri)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return GVIR_CONNECTION(g_object_new(GVIR_TYPE_CONNECTION,
|
|
Packit |
a07778 |
"uri", uri,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static int domain_event_cb(virConnectPtr conn G_GNUC_UNUSED,
|
|
Packit |
a07778 |
virDomainPtr dom,
|
|
Packit |
a07778 |
int event,
|
|
Packit |
a07778 |
int detail,
|
|
Packit |
a07778 |
void *opaque)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar uuid[VIR_UUID_STRING_BUFLEN];
|
|
Packit |
a07778 |
GHashTable *doms;
|
|
Packit |
a07778 |
GVirConnection *gconn = opaque;
|
|
Packit |
a07778 |
GVirDomain *gdom;
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv = gconn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainGetUUIDString(dom, uuid) < 0) {
|
|
Packit |
a07778 |
gvir_warning("Failed to get domain UUID on %p", dom);
|
|
Packit |
a07778 |
return 0;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_debug("%s: %s event:%d, detail:%d", G_STRFUNC, uuid, event, detail);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
doms = g_hash_table_ref(priv->domains);
|
|
Packit |
a07778 |
gdom = g_hash_table_lookup(doms, uuid);
|
|
Packit |
a07778 |
if (gdom != NULL)
|
|
Packit |
a07778 |
g_object_ref(G_OBJECT(gdom));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (gdom == NULL) {
|
|
Packit |
a07778 |
gdom = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN, "handle", dom, NULL));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_insert(doms, (gpointer)gvir_domain_get_uuid(gdom),
|
|
Packit |
a07778 |
g_object_ref(G_OBJECT(gdom)));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (event) {
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_DEFINED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_DEFINED_ADDED)
|
|
Packit |
a07778 |
g_signal_emit(gconn, signals[VIR_DOMAIN_ADDED], 0, gdom);
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_DEFINED_UPDATED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "updated");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_UNDEFINED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) {
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_remove(doms, uuid);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_signal_emit(gconn, signals[VIR_DOMAIN_REMOVED], 0, gdom);
|
|
Packit |
a07778 |
} else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_STARTED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_STARTED_BOOTED) {
|
|
Packit |
a07778 |
if (!virDomainIsPersistent(dom))
|
|
Packit |
a07778 |
g_signal_emit(gconn, signals[VIR_DOMAIN_ADDED], 0, gdom);
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "started::booted");
|
|
Packit |
a07778 |
} else if (detail == VIR_DOMAIN_EVENT_STARTED_MIGRATED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "started::migrated");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STARTED_RESTORED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "started::restored");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "started::from-snapshot");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STARTED_WAKEUP)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "started::wakeup");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_SUSPENDED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_SUSPENDED_PAUSED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::paused");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::migrated");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_IOERROR)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::ioerror");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::watchdog");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_RESTORED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::restored");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "suspended::from-snapshot");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_RESUMED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_RESUMED_UNPAUSED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "resumed::unpaused");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_RESUMED_MIGRATED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "resumed::migrated");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "resumed::from-snapshot");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_STOPPED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::shutdown");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_DESTROYED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::destroyed");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_CRASHED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::crashed");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_MIGRATED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::migrated");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_SAVED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::saved");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_FAILED)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::failed");
|
|
Packit |
a07778 |
else if (detail == VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "stopped::from-snapshot");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainIsPersistent(dom) != 1) {
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_remove(doms, uuid);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_signal_emit(gconn, signals[VIR_DOMAIN_REMOVED], 0, gdom);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_SHUTDOWN:
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case VIR_DOMAIN_EVENT_PMSUSPENDED:
|
|
Packit |
a07778 |
if (detail == VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY)
|
|
Packit |
a07778 |
g_signal_emit_by_name(gdom, "pmsuspended::memory");
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
default:
|
|
Packit |
a07778 |
g_warn_if_reached();
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_unref(G_OBJECT(gdom));
|
|
Packit |
a07778 |
g_hash_table_unref(doms);
|
|
Packit |
a07778 |
return 0;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gboolean _gvir_connection_open(GVirConnection *conn,
|
|
Packit |
a07778 |
gboolean read_only,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->conn) {
|
|
Packit |
a07778 |
g_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Connection %s is already open"),
|
|
Packit |
a07778 |
priv->uri);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (read_only) {
|
|
Packit |
a07778 |
priv->conn = virConnectOpenReadOnly(priv->uri);
|
|
Packit |
a07778 |
priv->read_only = TRUE;
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
priv->conn = virConnectOpen(priv->uri);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to open %s"),
|
|
Packit |
a07778 |
priv->uri);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!priv->uri) {
|
|
Packit |
a07778 |
char *uri = virConnectGetURI(priv->conn);
|
|
Packit |
a07778 |
if (!uri) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to get connection URI"));
|
|
Packit |
a07778 |
virConnectClose(priv->conn);
|
|
Packit |
a07778 |
priv->conn = NULL;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
priv->uri = g_strdup(uri);
|
|
Packit |
a07778 |
free(uri);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virConnectDomainEventRegister(priv->conn, domain_event_cb, conn, NULL) == -1)
|
|
Packit |
a07778 |
gvir_warning("Failed to register domain events, ignoring");
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_signal_emit(conn, signals[VIR_CONNECTION_OPENED], 0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_open:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_open(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return _gvir_connection_open(conn, FALSE, cancellable, err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_connection_open_read_only(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return _gvir_connection_open(conn, TRUE, cancellable, err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_open_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_open(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_open_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_open_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_open_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_open_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_open_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_open_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_open_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_open_read_only_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_open_read_only(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_open_read_only_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_open_read_only_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_open_read_only_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_open_read_only_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_open_read_only_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_open_read_only_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_open_read_only_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_connection_is_open(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
gboolean open = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (!priv->conn)
|
|
Packit |
a07778 |
open = FALSE;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return open;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_connection_is_read_only(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return conn->priv->read_only;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
void gvir_connection_close(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_debug("Close GVirConnection=%p", conn);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->domains) {
|
|
Packit |
a07778 |
g_hash_table_unref(priv->domains);
|
|
Packit |
a07778 |
priv->domains = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->pools) {
|
|
Packit |
a07778 |
g_hash_table_unref(priv->pools);
|
|
Packit |
a07778 |
priv->pools = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->interfaces) {
|
|
Packit |
a07778 |
g_hash_table_unref(priv->interfaces);
|
|
Packit |
a07778 |
priv->interfaces = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->networks) {
|
|
Packit |
a07778 |
g_hash_table_unref(priv->networks);
|
|
Packit |
a07778 |
priv->networks = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->conn) {
|
|
Packit |
a07778 |
virConnectDomainEventDeregister(priv->conn, domain_event_cb);
|
|
Packit |
a07778 |
virConnectClose(priv->conn);
|
|
Packit |
a07778 |
priv->conn = NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
/* xxx signals */
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_signal_emit(conn, signals[VIR_CONNECTION_CLOSED], 0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_domains:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Use this method to fetch all domains managed by connection
|
|
Packit |
a07778 |
* @conn. Use e.g. #gvir_connection_find_domain_by_id or
|
|
Packit |
a07778 |
* #gvir_connection_get_domain afterwards to query the fetched
|
|
Packit |
a07778 |
* domains.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_domains(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTable *doms;
|
|
Packit |
a07778 |
virDomainPtr *domains = NULL;
|
|
Packit |
a07778 |
gint ndomains = 0;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
gint i;
|
|
Packit |
a07778 |
virConnectPtr vconn = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Connection is not open"));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
vconn = priv->conn;
|
|
Packit |
a07778 |
/* Stop another thread closing the connection just at the minute */
|
|
Packit |
a07778 |
virConnectRef(vconn);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ndomains = virConnectListAllDomains(vconn, &domains, 0);
|
|
Packit |
a07778 |
if (ndomains < 0) {
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to fetch list of domains"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
doms = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (i = 0 ; i < ndomains; i++) {
|
|
Packit |
a07778 |
GVirDomain *dom;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
dom = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
|
|
Packit |
a07778 |
"handle", domains[i],
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_hash_table_insert(doms,
|
|
Packit |
a07778 |
(gpointer)gvir_domain_get_uuid(dom),
|
|
Packit |
a07778 |
dom);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->domains)
|
|
Packit |
a07778 |
g_hash_table_unref(priv->domains);
|
|
Packit |
a07778 |
priv->domains = doms;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
if (ndomains > 0) {
|
|
Packit |
a07778 |
for (i = 0 ; i < ndomains; i++)
|
|
Packit |
a07778 |
virDomainFree(domains[i]);
|
|
Packit |
a07778 |
free(domains);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (vconn != NULL)
|
|
Packit |
a07778 |
virConnectClose(vconn);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_storage_pools:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Use this method to fetch all storage pools managed by connection
|
|
Packit |
a07778 |
* @conn. Use e.g. #gvir_connection_find_storage_pool_by_name or
|
|
Packit |
a07778 |
* #gvir_connection_get_storage_pools afterwards to query the fetched
|
|
Packit |
a07778 |
* pools.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_storage_pools(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTable *pools;
|
|
Packit |
a07778 |
virStoragePoolPtr *vpools = NULL;
|
|
Packit |
a07778 |
gint npools = 0;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
gint i;
|
|
Packit |
a07778 |
virConnectPtr vconn = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Connection is not open"));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
vconn = priv->conn;
|
|
Packit |
a07778 |
/* Stop another thread closing the connection just at the minute */
|
|
Packit |
a07778 |
virConnectRef(vconn);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
npools = virConnectListAllStoragePools(vconn, &vpools, 0);
|
|
Packit |
a07778 |
if (npools < 0) {
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to fetch list of pools"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
pools = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (i = 0 ; i < npools; i++) {
|
|
Packit |
a07778 |
GVirStoragePool *pool;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
|
|
Packit |
a07778 |
"handle", vpools[i],
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
g_hash_table_insert(pools,
|
|
Packit |
a07778 |
(gpointer)gvir_storage_pool_get_uuid(pool),
|
|
Packit |
a07778 |
pool);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->pools)
|
|
Packit |
a07778 |
g_hash_table_unref(priv->pools);
|
|
Packit |
a07778 |
priv->pools = pools;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
if (npools > 0) {
|
|
Packit |
a07778 |
for (i = 0 ; i < npools; i++)
|
|
Packit |
a07778 |
virStoragePoolFree(vpools[i]);
|
|
Packit |
a07778 |
free(vpools);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (vconn != NULL)
|
|
Packit |
a07778 |
virConnectClose(vconn);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_fetch_domains_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_fetch_domains(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_domains_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_fetch_domains_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_domains_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_domains_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_domains_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_domains_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_fetch_domains_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_fetch_pools_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_fetch_storage_pools(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_storage_pools_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_fetch_storage_pools_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_storage_pools_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_pools_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_storage_pools_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_storage_pools_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_fetch_storage_pools_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
const gchar *gvir_connection_get_uri(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return conn->priv->uri;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_hypervisor_name:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get name of current hypervisor used.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: new string that should be freed when no longer needed,
|
|
Packit |
a07778 |
* or NULL upon error.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gchar *
|
|
Packit |
a07778 |
gvir_connection_get_hypervisor_name(GVirConnection *conn,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
gchar *ret = NULL;
|
|
Packit |
a07778 |
const char *type;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR, 0,
|
|
Packit |
a07778 |
_("Connection is not opened"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
type = virConnectGetType(priv->conn);
|
|
Packit |
a07778 |
if (!type) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR, 0,
|
|
Packit |
a07778 |
_("Unable to get hypervisor name"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = g_strdup(type);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_version:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get version of current hypervisor used.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: version on success, 0 otherwise and @err set.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gulong
|
|
Packit |
a07778 |
gvir_connection_get_version(GVirConnection *conn,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
gulong ret = 0;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, 0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR, 0,
|
|
Packit |
a07778 |
_("Connection is not opened"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virConnectGetVersion(priv->conn, &ret) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR, 0,
|
|
Packit |
a07778 |
_("Unable to get hypervisor version"));
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_domain_ref(gpointer obj, gpointer ignore G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_object_ref(obj);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_domains:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Gets a list of the domains available through @conn.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (element-type LibvirtGObject.Domain) (transfer full): List
|
|
Packit |
a07778 |
* of #GVirDomain. The returned list should be freed with g_list_free(),
|
|
Packit |
a07778 |
* after its elements have been unreffed with g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_connection_get_domains(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GList *domains = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->domains != NULL) {
|
|
Packit |
a07778 |
domains = g_hash_table_get_values(priv->domains);
|
|
Packit |
a07778 |
g_list_foreach(domains, gvir_domain_ref, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return domains;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_storage_pools:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Gets a list of the storage pools available through @conn.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (element-type LibvirtGObject.StoragePool) (transfer full): List
|
|
Packit |
a07778 |
* of #GVirStoragePool. The returned list should be freed with
|
|
Packit |
a07778 |
* g_list_free(), after its elements have been unreffed with
|
|
Packit |
a07778 |
* g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_connection_get_storage_pools(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GList *pools = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->pools != NULL) {
|
|
Packit |
a07778 |
pools = g_hash_table_get_values(priv->pools);
|
|
Packit |
a07778 |
g_list_foreach(pools, gvir_domain_ref, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return pools;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_domain:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @uuid: uuid string of the requested domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): the #GVirDomain, or NULL. The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomain *gvir_connection_get_domain(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *uuid)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GVirDomain *dom;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(uuid != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
dom = g_hash_table_lookup(priv->domains, uuid);
|
|
Packit |
a07778 |
if (dom)
|
|
Packit |
a07778 |
g_object_ref(dom);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return dom;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_storage_pool:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @uuid: uuid string of the requested storage pool
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): the #GVirStoragePool, or NULL. The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirStoragePool *gvir_connection_get_storage_pool(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *uuid)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GVirStoragePool *pool;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(uuid != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
pool = g_hash_table_lookup(priv->pools, uuid);
|
|
Packit |
a07778 |
if (pool)
|
|
Packit |
a07778 |
g_object_ref(pool);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return pool;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_find_domain_by_id:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @id: id of the requested domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): the #GVirDomain, or NULL. The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomain *gvir_connection_find_domain_by_id(GVirConnection *conn,
|
|
Packit |
a07778 |
gint id)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTableIter iter;
|
|
Packit |
a07778 |
gpointer key, value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_iter_init(&iter, priv->domains);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
Packit |
a07778 |
GVirDomain *dom = value;
|
|
Packit |
a07778 |
gint thisid = gvir_domain_get_id(dom, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (thisid == id) {
|
|
Packit |
a07778 |
g_object_ref(dom);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return dom;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_find_domain_by_name:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @name: name of the requested domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): the #GVirDomain, or NULL. The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomain *gvir_connection_find_domain_by_name(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTableIter iter;
|
|
Packit |
a07778 |
gpointer key, value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_iter_init(&iter, priv->domains);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
Packit |
a07778 |
GVirDomain *dom = value;
|
|
Packit |
a07778 |
const gchar *thisname = gvir_domain_get_name(dom);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (thisname == NULL)
|
|
Packit |
a07778 |
continue;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (strcmp(thisname, name) == 0) {
|
|
Packit |
a07778 |
g_object_ref(dom);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return dom;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_find_storage_pool_by_name:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @name: name of the requested storage pool
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): the #GVirStoragePool, or NULL. The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirStoragePool *gvir_connection_find_storage_pool_by_name(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTableIter iter;
|
|
Packit |
a07778 |
gpointer key, value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_iter_init(&iter, priv->pools);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
Packit |
a07778 |
GVirStoragePool *pool = value;
|
|
Packit |
a07778 |
const gchar *thisname = gvir_storage_pool_get_name(pool);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (thisname == NULL)
|
|
Packit |
a07778 |
continue;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (strcmp(thisname, name) == 0) {
|
|
Packit |
a07778 |
g_object_ref(pool);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return pool;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
typedef struct virConnect GVirConnectionHandle;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GVirConnectionHandle*
|
|
Packit |
a07778 |
gvir_connection_handle_copy(GVirConnectionHandle *src)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
virConnectRef((virConnectPtr)src);
|
|
Packit |
a07778 |
return src;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_handle_free(GVirConnectionHandle *src)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
virConnectClose((virConnectPtr)src);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_BOXED_TYPE(GVirConnectionHandle, gvir_connection_handle,
|
|
Packit |
a07778 |
gvir_connection_handle_copy, gvir_connection_handle_free)
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_stream:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @flags: flags to use for the stream
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): a #GVirStream stream, or NULL.The returned
|
|
Packit |
a07778 |
* object should be unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirStream *gvir_connection_get_stream(GVirConnection *self,
|
|
Packit |
a07778 |
guint flags)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionClass *klass;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(self), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(self->priv->conn, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
klass = GVIR_CONNECTION_GET_CLASS(self);
|
|
Packit |
a07778 |
g_return_val_if_fail(klass->stream_new, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
virStreamPtr st = virStreamNew(self->priv->conn, flags | VIR_STREAM_NONBLOCK);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return klass->stream_new(self, st);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_create_domain:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection on which to create the domain
|
|
Packit |
a07778 |
* @conf: the configuration for the new domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Create the configuration file for a new persistent domain.
|
|
Packit |
a07778 |
* The returned domain will initially be in the shutoff state.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the newly created domain, or NULL if an error
|
|
Packit |
a07778 |
* occurred. The returned object should be unreffed with g_object_unref()
|
|
Packit |
a07778 |
* when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomain *gvir_connection_create_domain(GVirConnection *conn,
|
|
Packit |
a07778 |
GVirConfigDomain *conf,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
virDomainPtr handle;
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(conf), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(xml != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
handle = virDomainDefineXML(priv->conn, xml);
|
|
Packit |
a07778 |
g_free(xml);
|
|
Packit |
a07778 |
if (!handle) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to create domain"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirDomain *domain;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
domain = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
|
|
Packit |
a07778 |
"handle", handle,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
virDomainFree(handle);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_insert(priv->domains,
|
|
Packit |
a07778 |
(gpointer)gvir_domain_get_uuid(domain),
|
|
Packit |
a07778 |
g_object_ref(domain));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return domain;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_start_domain:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection on which to create the domain
|
|
Packit |
a07778 |
* @conf: the configuration for the new domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Start a new transient domain without persistent configuration.
|
|
Packit |
a07778 |
* The returned domain will initially be running.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the newly created domain, or NULL if an error
|
|
Packit |
a07778 |
* occurred. The returned object should be unreffed with g_object_unref()
|
|
Packit |
a07778 |
* when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomain *gvir_connection_start_domain(GVirConnection *conn,
|
|
Packit |
a07778 |
GVirConfigDomain *conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
virDomainPtr handle;
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(conf), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(xml != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
handle = virDomainCreateXML(priv->conn, xml, flags);
|
|
Packit |
a07778 |
g_free(xml);
|
|
Packit |
a07778 |
if (!handle) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to create domain"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirDomain *domain;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
domain = GVIR_DOMAIN(g_object_new(GVIR_TYPE_DOMAIN,
|
|
Packit |
a07778 |
"handle", handle,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
virDomainFree(handle);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_insert(priv->domains,
|
|
Packit |
a07778 |
(gpointer)gvir_domain_get_uuid(domain),
|
|
Packit |
a07778 |
g_object_ref(domain));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return domain;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_interfaces:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @err: return location for any errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Use this method to fetch information on all network interfaces
|
|
Packit |
a07778 |
* managed by connection @conn on host machine. Use
|
|
Packit |
a07778 |
* #gvir_connection_get_interfaces or #gvir_connection_get_interface afterwards
|
|
Packit |
a07778 |
* to query the fetched interfaces.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: %TRUE on success, %FALSE otherwise and @err is set.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_interfaces(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTable *interfaces;
|
|
Packit |
a07778 |
virInterfacePtr *ifaces = NULL;
|
|
Packit |
a07778 |
gint ninterfaces = 0;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
gint i;
|
|
Packit |
a07778 |
virConnectPtr vconn = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Connection is not open"));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
vconn = priv->conn;
|
|
Packit |
a07778 |
/* Stop another thread closing the connection just at the minute */
|
|
Packit |
a07778 |
virConnectRef(vconn);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ninterfaces = virConnectListAllInterfaces(vconn, &ifaces, 0);
|
|
Packit |
a07778 |
if (ninterfaces < 0) {
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to fetch list of interfaces"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
interfaces = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (i = 0 ; i < ninterfaces; i++) {
|
|
Packit |
a07778 |
GVirInterface *iface;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
iface = GVIR_INTERFACE(g_object_new(GVIR_TYPE_INTERFACE,
|
|
Packit |
a07778 |
"handle", ifaces[i],
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_hash_table_insert(interfaces,
|
|
Packit |
a07778 |
(gpointer)gvir_interface_get_name(iface),
|
|
Packit |
a07778 |
iface);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->interfaces)
|
|
Packit |
a07778 |
g_hash_table_unref(priv->interfaces);
|
|
Packit |
a07778 |
priv->interfaces = interfaces;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
if (ninterfaces > 0) {
|
|
Packit |
a07778 |
for (i = 0 ; i < ninterfaces; i++)
|
|
Packit |
a07778 |
virInterfaceFree(ifaces[i]);
|
|
Packit |
a07778 |
free(ifaces);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (vconn != NULL)
|
|
Packit |
a07778 |
virConnectClose(vconn);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_fetch_interfaces_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_fetch_interfaces(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_interfaces_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_fetch_interfaces_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_interfaces_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_interfaces_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_interfaces_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
* @err: return location for any errors
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_interfaces_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_fetch_interfaces_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_interfaces:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a list of all the network interfaces managed by connection @conn on
|
|
Packit |
a07778 |
* host machine.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (element-type LibvirtGObject.Interface) (transfer full): List
|
|
Packit |
a07778 |
* of #GVirInterface. The returned list should be freed with g_list_free(),
|
|
Packit |
a07778 |
* after its elements have been unreffed with g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_connection_get_interfaces(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GList *interfaces = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->interfaces != NULL) {
|
|
Packit |
a07778 |
interfaces = g_hash_table_get_values(priv->interfaces);
|
|
Packit |
a07778 |
g_list_foreach(interfaces, gvir_domain_ref, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return interfaces;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_interface:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @name: interface name to lookup
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a particular interface which has name @name.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): A new reference to a #GVirInterface, or NULL
|
|
Packit |
a07778 |
* if no interface exists with name @name. The returned object must be unreffed
|
|
Packit |
a07778 |
* using g_object_unref() once used.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirInterface *gvir_connection_get_interface(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GVirInterface *iface;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
iface = g_hash_table_lookup(priv->interfaces, name);
|
|
Packit |
a07778 |
if (iface)
|
|
Packit |
a07778 |
g_object_ref(iface);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return iface;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_find_interface_by_mac:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @macaddr: MAC address to lookup
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a particular interface which has MAC address @mac.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): A new reference to a #GVirInterface, or NULL
|
|
Packit |
a07778 |
* if no interface exists with MAC address @mac. The returned object must be
|
|
Packit |
a07778 |
* unreffed using g_object_unref() once used.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirInterface *gvir_connection_find_interface_by_mac(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *mac)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTableIter iter;
|
|
Packit |
a07778 |
gpointer key, value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(mac != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_iter_init(&iter, priv->interfaces);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
Packit |
a07778 |
GVirInterface *iface = value;
|
|
Packit |
a07778 |
const gchar *thismac = gvir_interface_get_mac(iface);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_strcmp0(thismac, mac) == 0) {
|
|
Packit |
a07778 |
g_object_ref(iface);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return iface;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_networks:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Use this method to fetch all networks managed by connection
|
|
Packit |
a07778 |
* @conn. Use e.g. #gvir_connection_find_network_by_name or
|
|
Packit |
a07778 |
* #gvir_connection_get_networks afterwards to query the fetched
|
|
Packit |
a07778 |
* domains.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_networks(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTable *networks;
|
|
Packit |
a07778 |
virNetworkPtr *vnetworks = NULL;
|
|
Packit |
a07778 |
gint nnetworks = 0;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
gint i;
|
|
Packit |
a07778 |
virConnectPtr vconn = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (!priv->conn) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Connection is not open"));
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
vconn = priv->conn;
|
|
Packit |
a07778 |
/* Stop another thread closing the connection just at the minute */
|
|
Packit |
a07778 |
virConnectRef(vconn);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
nnetworks = virConnectListAllNetworks(vconn, &vnetworks, 0);
|
|
Packit |
a07778 |
if (nnetworks < 0) {
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Failed to fetch list of networks"));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
networks = g_hash_table_new_full(g_str_hash,
|
|
Packit |
a07778 |
g_str_equal,
|
|
Packit |
a07778 |
NULL,
|
|
Packit |
a07778 |
g_object_unref);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (i = 0 ; i < nnetworks; i++) {
|
|
Packit |
a07778 |
GVirNetwork *network;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, err))
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
network = GVIR_NETWORK(g_object_new(GVIR_TYPE_NETWORK,
|
|
Packit |
a07778 |
"handle", vnetworks[i],
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
g_hash_table_insert(networks,
|
|
Packit |
a07778 |
(gpointer)gvir_network_get_uuid(network),
|
|
Packit |
a07778 |
network);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->networks)
|
|
Packit |
a07778 |
g_hash_table_unref(priv->networks);
|
|
Packit |
a07778 |
priv->networks = networks;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
if (nnetworks > 0) {
|
|
Packit |
a07778 |
for (i = 0 ; i < nnetworks; i++)
|
|
Packit |
a07778 |
virNetworkFree(vnetworks[i]);
|
|
Packit |
a07778 |
free(vnetworks);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
if (vconn != NULL)
|
|
Packit |
a07778 |
virConnectClose(vconn);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_fetch_networks_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_fetch_networks(conn, cancellable, &err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_networks_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_fetch_networks_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_networks_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_fetch_networks_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_fetch_networks_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
* @err: return location for any errors
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_fetch_networks_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_fetch_networks_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_networks:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a list of all the network networks available through @conn.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (element-type LibvirtGObject.Network) (transfer full): List
|
|
Packit |
a07778 |
* of #GVirNetwork. The returned list should be freed with g_list_free(),
|
|
Packit |
a07778 |
* after its elements have been unreffed with g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_connection_get_networks(GVirConnection *conn)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GList *networks = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->networks != NULL) {
|
|
Packit |
a07778 |
networks = g_hash_table_get_values(priv->networks);
|
|
Packit |
a07778 |
g_list_foreach(networks, gvir_domain_ref, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return networks;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_network:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @uuid: UUID of the network to lookup
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a particular network which has UUID @uuid.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): A new reference to a #GVirNetwork, or NULL if
|
|
Packit |
a07778 |
* no network exists with UUID @uuid. The returned object must be unreffed using
|
|
Packit |
a07778 |
* g_object_unref() once used.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirNetwork *gvir_connection_get_network(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *uuid)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GVirNetwork *network;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(uuid != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
network = g_hash_table_lookup(priv->networks, uuid);
|
|
Packit |
a07778 |
if (network)
|
|
Packit |
a07778 |
g_object_ref(network);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return network;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_find_network_by_name:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @name: name of the network to search for
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Get a particular network which has name @name.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): A new reference to a #GVirNetwork, or NULL if
|
|
Packit |
a07778 |
* no network exists with name @name. The returned object must be unreffed using
|
|
Packit |
a07778 |
* g_object_unref() once used.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirNetwork *gvir_connection_find_network_by_name(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *name)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
GHashTableIter iter;
|
|
Packit |
a07778 |
gpointer key, value;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(name != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_iter_init(&iter, priv->networks);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
while (g_hash_table_iter_next(&iter, &key, &value)) {
|
|
Packit |
a07778 |
GVirNetwork *network = value;
|
|
Packit |
a07778 |
const gchar *thisname = gvir_network_get_name(network);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (thisname == NULL)
|
|
Packit |
a07778 |
continue;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (strcmp(thisname, name) == 0) {
|
|
Packit |
a07778 |
g_object_ref(network);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
return network;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_create_storage_pool:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection on which to create the pool
|
|
Packit |
a07778 |
* @conf: the configuration for the new storage pool
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the newly created storage pool, or NULL if an
|
|
Packit |
a07778 |
* error occurred. The returned list should be freed with g_list_free(),
|
|
Packit |
a07778 |
* after its elements have been unreffed with g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirStoragePool *gvir_connection_create_storage_pool
|
|
Packit |
a07778 |
(GVirConnection *conn,
|
|
Packit |
a07778 |
GVirConfigStoragePool *conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err) {
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
virStoragePoolPtr handle;
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_STORAGE_POOL(conf), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(xml != NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
handle = virStoragePoolDefineXML(priv->conn, xml, flags);
|
|
Packit |
a07778 |
g_free(xml);
|
|
Packit |
a07778 |
if (!handle) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
flags,
|
|
Packit |
a07778 |
_("Failed to create storage pool"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirStoragePool *pool;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
pool = GVIR_STORAGE_POOL(g_object_new(GVIR_TYPE_STORAGE_POOL,
|
|
Packit |
a07778 |
"handle", handle,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
virStoragePoolFree(handle);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
g_hash_table_insert(priv->pools,
|
|
Packit |
a07778 |
(gpointer)gvir_storage_pool_get_uuid(pool),
|
|
Packit |
a07778 |
pool);
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_object_ref(pool);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_node_info:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the info, or NULL if an error occurred. The
|
|
Packit |
a07778 |
* returned object should be unreffed with g_object_unref() when no longer
|
|
Packit |
a07778 |
* needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirNodeInfo *gvir_connection_get_node_info(GVirConnection *conn,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
virNodeInfo info;
|
|
Packit |
a07778 |
GVirNodeInfo *ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
if (virNodeGetInfo(priv->conn, &info) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to get node info"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = g_slice_new(GVirNodeInfo);
|
|
Packit |
a07778 |
g_strlcpy (ret->model, info.model, sizeof (ret->model));
|
|
Packit |
a07778 |
ret->memory = info.memory;
|
|
Packit |
a07778 |
ret->cpus = info.cpus;
|
|
Packit |
a07778 |
ret->mhz = info.mhz;
|
|
Packit |
a07778 |
ret->nodes = info.nodes;
|
|
Packit |
a07778 |
ret->sockets = info.sockets;
|
|
Packit |
a07778 |
ret->cores = info.cores;
|
|
Packit |
a07778 |
ret->threads = info.threads;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_domain_capabilities:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @emulatorbin: (allow-none): path to emulator
|
|
Packit |
a07778 |
* @arch: (allow-none): domain architecture
|
|
Packit |
a07778 |
* @machine: (allow-none): machine type
|
|
Packit |
a07778 |
* @virttype: (allow-none): virtualization type
|
|
Packit |
a07778 |
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): a #GVirConfigDomainCapabilities or NULL.
|
|
Packit |
a07778 |
* The return object should be unreffed with g_object_unref() when no longer
|
|
Packit |
a07778 |
* needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirConfigDomainCapabilities *
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *emulatorbin,
|
|
Packit |
a07778 |
const gchar *arch,
|
|
Packit |
a07778 |
const gchar *machine,
|
|
Packit |
a07778 |
const gchar *virttype,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigDomainCapabilities *domain_caps;
|
|
Packit |
a07778 |
gchar *domain_caps_xml;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(conn->priv->conn, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
domain_caps_xml = virConnectGetDomainCapabilities(conn->priv->conn,
|
|
Packit |
a07778 |
emulatorbin,
|
|
Packit |
a07778 |
arch,
|
|
Packit |
a07778 |
machine,
|
|
Packit |
a07778 |
virttype,
|
|
Packit |
a07778 |
flags);
|
|
Packit |
a07778 |
if (domain_caps_xml == NULL) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to get domain capabilities"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
domain_caps = gvir_config_domain_capabilities_new_from_xml(domain_caps_xml, err);
|
|
Packit |
a07778 |
free(domain_caps_xml);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return domain_caps;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
typedef struct {
|
|
Packit |
a07778 |
gchar *emulatorbin;
|
|
Packit |
a07778 |
gchar *arch;
|
|
Packit |
a07778 |
gchar *machine;
|
|
Packit |
a07778 |
gchar *virttype;
|
|
Packit |
a07778 |
guint flags;
|
|
Packit |
a07778 |
} GetDomainCapabilitiesData;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void get_domain_capabilities_data_free(GetDomainCapabilitiesData *data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_free(data->emulatorbin);
|
|
Packit |
a07778 |
g_free(data->arch);
|
|
Packit |
a07778 |
g_free(data->machine);
|
|
Packit |
a07778 |
g_free(data->virttype);
|
|
Packit |
a07778 |
g_slice_free(GetDomainCapabilitiesData, data);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GetDomainCapabilitiesData *data;
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
GVirConfigDomainCapabilities *domain_caps;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
data = (GetDomainCapabilitiesData *)task_data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
domain_caps = gvir_connection_get_domain_capabilities(conn,
|
|
Packit |
a07778 |
data->emulatorbin,
|
|
Packit |
a07778 |
data->arch,
|
|
Packit |
a07778 |
data->machine,
|
|
Packit |
a07778 |
data->virttype,
|
|
Packit |
a07778 |
data->flags,
|
|
Packit |
a07778 |
&err;;
|
|
Packit |
a07778 |
if (domain_caps == NULL) {
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_task_return_pointer(task, domain_caps, g_object_unref);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_domain_capabilities_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @emulatorbin: (allow-none): path to emulator
|
|
Packit |
a07778 |
* @arch: (allow-none): domain architecture
|
|
Packit |
a07778 |
* @machine: (allow-none): machine type
|
|
Packit |
a07778 |
* @virttype: (allow-none): virtualization type
|
|
Packit |
a07778 |
* @flags: extra flags; not used yet, so callers should always pass 0
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_get_domain_capabilities_async(GVirConnection *conn,
|
|
Packit |
a07778 |
const gchar *emulatorbin,
|
|
Packit |
a07778 |
const gchar *arch,
|
|
Packit |
a07778 |
const gchar *machine,
|
|
Packit |
a07778 |
const gchar *virttype,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
GetDomainCapabilitiesData *data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
data = g_slice_new0(GetDomainCapabilitiesData);
|
|
Packit |
a07778 |
data->emulatorbin = g_strdup(emulatorbin);
|
|
Packit |
a07778 |
data->arch = g_strdup(arch);
|
|
Packit |
a07778 |
data->machine = g_strdup(machine);
|
|
Packit |
a07778 |
data->virttype = g_strdup(virttype);
|
|
Packit |
a07778 |
data->flags = flags;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities_async);
|
|
Packit |
a07778 |
g_task_set_task_data(task,
|
|
Packit |
a07778 |
data,
|
|
Packit |
a07778 |
(GDestroyNotify)get_domain_capabilities_data_free);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_domain_capabilities_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): a #GVirConfigDomainCapabilities or NULL.
|
|
Packit |
a07778 |
* The returned object should be unreffed with g_object_unref() when no
|
|
Packit |
a07778 |
* longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirConfigDomainCapabilities *
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_get_domain_capabilities_async,
|
|
Packit |
a07778 |
NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_pointer(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_capabilities:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @err: return location for any #GError
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): a #GVirConfigCapabilities or NULL. The
|
|
Packit |
a07778 |
* returned object should be unreffed with g_object_unref() when no longer
|
|
Packit |
a07778 |
* needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirConfigCapabilities *gvir_connection_get_capabilities(GVirConnection *conn,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigCapabilities *caps;
|
|
Packit |
a07778 |
char *caps_xml;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(conn->priv->conn, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
caps_xml = virConnectGetCapabilities(conn->priv->conn);
|
|
Packit |
a07778 |
if (caps_xml == NULL) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to get capabilities"));
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
caps = gvir_config_capabilities_new_from_xml(caps_xml, err);
|
|
Packit |
a07778 |
free(caps_xml);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return caps;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_get_capabilities_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
GVirConfigCapabilities *caps;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
caps = gvir_connection_get_capabilities(conn, &err;;
|
|
Packit |
a07778 |
if (caps == NULL) {
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_task_return_pointer(task, caps, g_object_unref);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_capabilities_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @cancellable: (allow-none)(transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_connection_get_capabilities_async(GVirConnection *conn,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_get_capabilities_async);
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_get_capabilities_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_get_capabilities_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Return value: (transfer full): a #GVirConfigCapabilities or NULL. The
|
|
Packit |
a07778 |
* returned object should be unreffed with g_object_unref() when no longer
|
|
Packit |
a07778 |
* needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirConfigCapabilities *
|
|
Packit |
a07778 |
gvir_connection_get_capabilities_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_get_capabilities_async,
|
|
Packit |
a07778 |
NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_pointer(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_restore_domain_from_file:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @filename: path to input file
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): configuration for domain or NULL
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Restores the domain saved with #gvir_domain_save_to_file
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success, FALSE otherwise
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_connection_restore_domain_from_file(GVirConnection *conn,
|
|
Packit |
a07778 |
gchar *filename,
|
|
Packit |
a07778 |
GVirConfigDomain *custom_conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnectionPrivate *priv;
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((filename != NULL), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((err == NULL) || (*err == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = conn->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (flags || (custom_conf != NULL)) {
|
|
Packit |
a07778 |
gchar *custom_xml = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (custom_conf != NULL)
|
|
Packit |
a07778 |
custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = virDomainRestoreFlags(priv->conn, filename, custom_xml, flags);
|
|
Packit |
a07778 |
g_free (custom_xml);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
else {
|
|
Packit |
a07778 |
ret = virDomainRestore(priv->conn, filename);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_CONNECTION_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
_("Unable to restore domain"));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
typedef struct {
|
|
Packit |
a07778 |
gchar *filename;
|
|
Packit |
a07778 |
GVirConfigDomain *custom_conf;
|
|
Packit |
a07778 |
guint flags;
|
|
Packit |
a07778 |
} RestoreDomainFromFileData;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void restore_domain_from_file_data_free(RestoreDomainFromFileData *data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_free(data->filename);
|
|
Packit |
a07778 |
g_clear_object(&data->custom_conf);
|
|
Packit |
a07778 |
g_slice_free(RestoreDomainFromFileData, data);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_helper
|
|
Packit |
a07778 |
(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConnection *conn = GVIR_CONNECTION(object);
|
|
Packit |
a07778 |
RestoreDomainFromFileData *data;
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
data = (RestoreDomainFromFileData *)task_data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_connection_restore_domain_from_file(conn,
|
|
Packit |
a07778 |
data->filename,
|
|
Packit |
a07778 |
data->custom_conf,
|
|
Packit |
a07778 |
data->flags,
|
|
Packit |
a07778 |
&err))
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_restore_domain_from_file_async:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @filename: path to input file
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): configuration for domain
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
* @cancellable: (allow-none) (transfer none): cancellation object
|
|
Packit |
a07778 |
* @callback: (scope async): completion callback
|
|
Packit |
a07778 |
* @user_data: (closure): opaque data for callback
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Asynchronous variant of #gvir_connection_restore_domain_from_file
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_async(GVirConnection *conn,
|
|
Packit |
a07778 |
gchar *filename,
|
|
Packit |
a07778 |
GVirConfigDomain *custom_conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
RestoreDomainFromFileData *data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_CONNECTION(conn));
|
|
Packit |
a07778 |
g_return_if_fail(filename != NULL);
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
data = g_slice_new0(RestoreDomainFromFileData);
|
|
Packit |
a07778 |
data->filename = g_strdup(filename);
|
|
Packit |
a07778 |
if (custom_conf != NULL)
|
|
Packit |
a07778 |
data->custom_conf = g_object_ref(custom_conf);
|
|
Packit |
a07778 |
data->flags = flags;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(conn),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_source_tag(task,
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_async);
|
|
Packit |
a07778 |
g_task_set_task_data(task,
|
|
Packit |
a07778 |
data,
|
|
Packit |
a07778 |
(GDestroyNotify)restore_domain_from_file_data_free);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_task_run_in_thread(task,
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_helper);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_connection_restore_domain_from_file_finish:
|
|
Packit |
a07778 |
* @conn: a #GVirConnection
|
|
Packit |
a07778 |
* @result: (transfer none): async method result
|
|
Packit |
a07778 |
* @err: Place-holder for possible errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Finishes the operation started by #gvir_restore_domain_from_file_async.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain was restored successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_finish(GVirConnection *conn,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_CONNECTION(conn), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(conn)),
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_get_source_tag(G_TASK(result)) ==
|
|
Packit |
a07778 |
gvir_connection_restore_domain_from_file_async,
|
|
Packit |
a07778 |
FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|