|
Packit |
a07778 |
/*
|
|
Packit |
a07778 |
* libvirt-gobject-domain.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 <glib.h>
|
|
Packit |
a07778 |
#include <libvirt/virterror.h>
|
|
Packit |
a07778 |
#include <string.h>
|
|
Packit |
a07778 |
#if !defined(HAVE_VIR_DOMAIN_OPEN_GRAPHICS_FD) && !defined(G_OS_WIN32)
|
|
Packit |
a07778 |
#include <sys/socket.h>
|
|
Packit |
a07778 |
#endif
|
|
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 |
#include "libvirt-gobject/libvirt-gobject-domain-device-private.h"
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#define GVIR_DOMAIN_GET_PRIVATE(obj) \
|
|
Packit |
a07778 |
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_TYPE_DOMAIN, GVirDomainPrivate))
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
struct _GVirDomainPrivate
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
virDomainPtr handle;
|
|
Packit |
a07778 |
gchar uuid[VIR_UUID_STRING_BUFLEN];
|
|
Packit |
a07778 |
GHashTable *snapshots;
|
|
Packit |
a07778 |
GMutex *lock;
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_TYPE_WITH_PRIVATE(GVirDomain, gvir_domain, G_TYPE_OBJECT);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum {
|
|
Packit |
a07778 |
PROP_0,
|
|
Packit |
a07778 |
PROP_HANDLE,
|
|
Packit |
a07778 |
PROP_PERSISTENT,
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
enum {
|
|
Packit |
a07778 |
VIR_STARTED,
|
|
Packit |
a07778 |
VIR_SUSPENDED,
|
|
Packit |
a07778 |
VIR_RESUMED,
|
|
Packit |
a07778 |
VIR_STOPPED,
|
|
Packit |
a07778 |
VIR_UPDATED,
|
|
Packit |
a07778 |
VIR_PMSUSPENDED,
|
|
Packit |
a07778 |
LAST_SIGNAL
|
|
Packit |
a07778 |
};
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
typedef struct {
|
|
Packit |
a07778 |
guint create_flags;
|
|
Packit |
a07778 |
GVirConfigDomainSnapshot *snapshot_config;
|
|
Packit |
a07778 |
} SnapshotCreateData;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void snapshot_create_data_free (SnapshotCreateData *data) {
|
|
Packit |
a07778 |
g_clear_object (&data->snapshot_config);
|
|
Packit |
a07778 |
g_slice_free (SnapshotCreateData, data);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static gint signals[LAST_SIGNAL];
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#define GVIR_DOMAIN_ERROR gvir_domain_error_quark()
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GQuark
|
|
Packit |
a07778 |
gvir_domain_error_quark(void)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_quark_from_static_string("gvir-domain");
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_domain_get_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *domain = GVIR_DOMAIN(object);
|
|
Packit |
a07778 |
GVirDomainPrivate *priv = domain->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_HANDLE:
|
|
Packit |
a07778 |
g_value_set_boxed(value, priv->handle);
|
|
Packit |
a07778 |
break;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
case PROP_PERSISTENT:
|
|
Packit |
a07778 |
g_value_set_boolean(value, gvir_domain_get_persistent (domain));
|
|
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_domain_set_property(GObject *object,
|
|
Packit |
a07778 |
guint prop_id,
|
|
Packit |
a07778 |
const GValue *value,
|
|
Packit |
a07778 |
GParamSpec *pspec)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *domain = GVIR_DOMAIN(object);
|
|
Packit |
a07778 |
GVirDomainPrivate *priv = domain->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
switch (prop_id) {
|
|
Packit |
a07778 |
case PROP_HANDLE:
|
|
Packit |
a07778 |
if (priv->handle)
|
|
Packit |
a07778 |
virDomainFree(priv->handle);
|
|
Packit |
a07778 |
priv->handle = 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_domain_finalize(GObject *object)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *domain = GVIR_DOMAIN(object);
|
|
Packit |
a07778 |
GVirDomainPrivate *priv = domain->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (priv->snapshots) {
|
|
Packit |
a07778 |
g_hash_table_unref(priv->snapshots);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_free(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
virDomainFree(priv->handle);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_OBJECT_CLASS(gvir_domain_parent_class)->finalize(object);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_domain_constructed(GObject *object)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *domain = GVIR_DOMAIN(object);
|
|
Packit |
a07778 |
GVirDomainPrivate *priv = domain->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_OBJECT_CLASS(gvir_domain_parent_class)->constructed(object);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/* xxx we may want to turn this into an initable */
|
|
Packit |
a07778 |
if (virDomainGetUUIDString(priv->handle, priv->uuid) < 0)
|
|
Packit |
a07778 |
gvir_warning("Failed to get domain UUID on %p", priv->handle);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_domain_class_init(GVirDomainClass *klass)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
object_class->finalize = gvir_domain_finalize;
|
|
Packit |
a07778 |
object_class->get_property = gvir_domain_get_property;
|
|
Packit |
a07778 |
object_class->set_property = gvir_domain_set_property;
|
|
Packit |
a07778 |
object_class->constructed = gvir_domain_constructed;
|
|
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 domain handle",
|
|
Packit |
a07778 |
GVIR_TYPE_DOMAIN_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 |
g_object_class_install_property(object_class,
|
|
Packit |
a07778 |
PROP_PERSISTENT,
|
|
Packit |
a07778 |
g_param_spec_boolean("persistent",
|
|
Packit |
a07778 |
"Persistent",
|
|
Packit |
a07778 |
"If domain is persistent",
|
|
Packit |
a07778 |
TRUE,
|
|
Packit |
a07778 |
G_PARAM_READABLE |
|
|
Packit |
a07778 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
signals[VIR_STARTED] = g_signal_new("started",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
|
Packit |
a07778 |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, started),
|
|
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_SUSPENDED] = g_signal_new("suspended",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
|
Packit |
a07778 |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, suspended),
|
|
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_RESUMED] = g_signal_new("resumed",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
|
Packit |
a07778 |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, resumed),
|
|
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_STOPPED] = g_signal_new("stopped",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
|
Packit |
a07778 |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, stopped),
|
|
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_UPDATED] = g_signal_new("updated",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, updated),
|
|
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_PMSUSPENDED] = g_signal_new("pmsuspended",
|
|
Packit |
a07778 |
G_OBJECT_CLASS_TYPE(object_class),
|
|
Packit |
a07778 |
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
|
|
Packit |
a07778 |
G_SIGNAL_NO_HOOKS | G_SIGNAL_DETAILED,
|
|
Packit |
a07778 |
G_STRUCT_OFFSET(GVirDomainClass, pmsuspended),
|
|
Packit |
a07778 |
NULL, NULL,
|
|
Packit |
a07778 |
g_cclosure_marshal_VOID__VOID,
|
|
Packit |
a07778 |
G_TYPE_NONE,
|
|
Packit |
a07778 |
0);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void gvir_domain_init(GVirDomain *domain)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
domain->priv = GVIR_DOMAIN_GET_PRIVATE(domain);
|
|
Packit |
a07778 |
domain->priv->lock = g_mutex_new();
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
typedef struct virDomain GVirDomainHandle;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GVirDomainHandle*
|
|
Packit |
a07778 |
gvir_domain_handle_copy(GVirDomainHandle *src)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
virDomainRef((virDomainPtr)src);
|
|
Packit |
a07778 |
return src;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_handle_free(GVirDomainHandle *src)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
virDomainFree((virDomainPtr)src);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_BOXED_TYPE(GVirDomainHandle, gvir_domain_handle,
|
|
Packit |
a07778 |
gvir_domain_handle_copy, gvir_domain_handle_free)
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static GVirDomainInfo *
|
|
Packit |
a07778 |
gvir_domain_info_copy(GVirDomainInfo *info)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
return g_slice_dup(GVirDomainInfo, info);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_info_free(GVirDomainInfo *info)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_slice_free(GVirDomainInfo, info);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
G_DEFINE_BOXED_TYPE(GVirDomainInfo, gvir_domain_info,
|
|
Packit |
a07778 |
gvir_domain_info_copy, gvir_domain_info_free)
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
const gchar *gvir_domain_get_name(GVirDomain *dom)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
const char *name;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (!(name = virDomainGetName(priv->handle))) {
|
|
Packit |
a07778 |
gvir_warning("Failed to get domain name on %p", priv->handle);
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return name;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
const gchar *gvir_domain_get_uuid(GVirDomain *dom)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return dom->priv->uuid;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gint gvir_domain_get_id(GVirDomain *dom,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
gint ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), -1);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, -1);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if ((ret = virDomainGetID(priv->handle)) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to get ID for domain");
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_start:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_start(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (flags)
|
|
Packit |
a07778 |
ret = virDomainCreateWithFlags(priv->handle, flags);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
ret = virDomainCreate(priv->handle);
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to start domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_start_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
guint flags = GPOINTER_TO_UINT(task_data);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_start(dom, flags, &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_domain_start_async:
|
|
Packit |
a07778 |
* @dom: the 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_domain_start.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_start_async(GVirDomain *dom,
|
|
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 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task, GUINT_TO_POINTER(flags), NULL);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_start_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_domain_start_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_resume:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @err: Place-holder for possible errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_resume(GVirDomain *dom,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (virDomainResume(priv->handle) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to resume domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_resume_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_resume(dom, &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_domain_resume_async:
|
|
Packit |
a07778 |
* @dom: the domain to resume
|
|
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_domain_resume.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_resume_async(GVirDomain *dom,
|
|
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_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_resume_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_domain_resume_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_wakeup:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: placeholder for flags, pass 0
|
|
Packit |
a07778 |
* @err: Place-holder for possible errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_wakeup(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (virDomainPMWakeup(priv->handle, flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to wakeup domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_wakeup_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
guint flags = GPOINTER_TO_UINT(task_data);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_wakeup(dom, flags, &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_domain_wakeup_async:
|
|
Packit |
a07778 |
* @dom: the domain to wakeup
|
|
Packit |
a07778 |
* @flags: placeholder for flags, 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 |
* Asynchronous variant of #gvir_domain_wakeup.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_wakeup_async(GVirDomain *dom,
|
|
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 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task, GUINT_TO_POINTER(flags), NULL);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_wakeup_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gboolean gvir_domain_wakeup_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_stop:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_stop(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (flags)
|
|
Packit |
a07778 |
ret = virDomainDestroyFlags(priv->handle, flags);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
ret = virDomainDestroy(priv->handle);
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to stop domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_delete:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_delete(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (flags)
|
|
Packit |
a07778 |
ret = virDomainUndefineFlags(priv->handle, flags);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
ret = virDomainUndefine(priv->handle);
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to delete domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_shutdown:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the %GVirDomainShutdownFlags flags
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_shutdown(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (virDomainShutdownFlags(priv->handle, flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to shutdown domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_reboot:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the %GVirDomainRebootFlags flags
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_reboot(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (virDomainReboot(priv->handle, flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to reboot domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_save_to_file:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @filename: path to the output file
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): configuration for domain or NULL
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success, FALSE otherwise
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_save_to_file(GVirDomain *dom,
|
|
Packit |
a07778 |
gchar *filename,
|
|
Packit |
a07778 |
GVirConfigDomain *custom_conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), 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 = dom->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 = virDomainSaveFlags(priv->handle, filename, custom_xml, flags);
|
|
Packit |
a07778 |
g_free(custom_xml);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
else {
|
|
Packit |
a07778 |
ret = virDomainSave(priv->handle, filename);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to save domain to file");
|
|
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 |
} DomainSaveToFileData;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void domain_save_to_file_data_free(DomainSaveToFileData *data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_free(data->filename);
|
|
Packit |
a07778 |
g_clear_object(&data->custom_conf);
|
|
Packit |
a07778 |
g_slice_free(DomainSaveToFileData, data);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_save_to_file_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
DomainSaveToFileData *data = (DomainSaveToFileData *) task_data;
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_save_to_file(dom, data->filename, data->custom_conf, data->flags, &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_domain_save_to_file_async:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @filename: path to output file
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): configuration for domain or NULL
|
|
Packit |
a07778 |
* @flags: the flags
|
|
Packit |
a07778 |
* @cancellable: (allow-none) (transfer none): cancallation 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_domain_save_to_file
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_save_to_file_async(GVirDomain *dom,
|
|
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 |
DomainSaveToFileData *data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_DOMAIN(dom));
|
|
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(DomainSaveToFileData);
|
|
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(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task,
|
|
Packit |
a07778 |
data,
|
|
Packit |
a07778 |
(GDestroyNotify) domain_save_to_file_data_free);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_save_to_file_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_save_to_file_finish:
|
|
Packit |
a07778 |
* @dom: the domain to save
|
|
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_domain_save_to_file_async.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain was saved successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_config:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @flags: the %GVirDomainXMLFlags flags
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the config. The returned object should be
|
|
Packit |
a07778 |
* unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirConfigDomain *gvir_domain_get_config(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (!(xml = virDomainGetXMLDesc(priv->handle, flags))) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to get domain XML config");
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
GVirConfigDomain *conf = gvir_config_domain_new_from_xml(xml, err);
|
|
Packit |
a07778 |
g_free(xml);
|
|
Packit |
a07778 |
if ((err != NULL) && (*err != NULL))
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return conf;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_set_config:
|
|
Packit |
a07778 |
* @domain: the domain
|
|
Packit |
a07778 |
* @conf: the new configuration for the domain
|
|
Packit |
a07778 |
* @err: (allow-none): Place-holder for error or NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Resets configuration of an existing domain.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Note: If domain is already running, the new configuration will not take
|
|
Packit |
a07778 |
* affect until domain reboots.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success, FALSE if an error occurred.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_set_config(GVirDomain *domain,
|
|
Packit |
a07778 |
GVirConfigDomain *conf,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
virConnectPtr conn;
|
|
Packit |
a07778 |
virDomainPtr handle;
|
|
Packit |
a07778 |
gchar uuid[VIR_UUID_STRING_BUFLEN];
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN (domain), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN (conf), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = domain->priv;
|
|
Packit |
a07778 |
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(xml != NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if ((conn = virDomainGetConnect(priv->handle)) == NULL) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to get domain connection");
|
|
Packit |
a07778 |
g_free (xml);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
handle = virDomainDefineXML(conn, xml);
|
|
Packit |
a07778 |
g_free (xml);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (handle == NULL) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to set "
|
|
Packit |
a07778 |
"domain configuration");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
virDomainGetUUIDString(handle, uuid);
|
|
Packit |
a07778 |
virDomainFree(handle);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_strcmp0 (uuid, priv->uuid) != 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to set "
|
|
Packit |
a07778 |
"domain configuration");
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_info:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the info. The returned structure should be
|
|
Packit |
a07778 |
* freed using #g_boxed_free() with GVIR_TYPE_DOMAIN_INFO as the first argument
|
|
Packit |
a07778 |
* when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
virDomainInfo info;
|
|
Packit |
a07778 |
GVirDomainInfo *ret;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
if (virDomainGetInfo(priv->handle, &info) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to get domain info");
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = g_slice_new(GVirDomainInfo);
|
|
Packit |
a07778 |
ret->state = info.state;
|
|
Packit |
a07778 |
ret->maxMem = info.maxMem;
|
|
Packit |
a07778 |
ret->memory = info.memory;
|
|
Packit |
a07778 |
ret->nrVirtCpu = info.nrVirtCpu;
|
|
Packit |
a07778 |
ret->cpuTime = info.cpuTime;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_get_info_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
GVirDomainInfo *info;
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
info = gvir_domain_get_info(dom, &err;;
|
|
Packit |
a07778 |
if (err)
|
|
Packit |
a07778 |
g_task_return_error(task, err);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_pointer(task,
|
|
Packit |
a07778 |
info,
|
|
Packit |
a07778 |
(GDestroyNotify) gvir_domain_info_free);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_info_async:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
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_domain_get_info.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_get_info_async(GVirDomain *dom,
|
|
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_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_get_info_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_info_finish:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
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_domain_get_info_async.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): the info. The returned object should be
|
|
Packit |
a07778 |
* unreffed with g_object_unref() when no longer needed.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomainInfo *gvir_domain_get_info_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_pointer(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_screenshot:
|
|
Packit |
a07778 |
* @stream: stream to use as output
|
|
Packit |
a07778 |
* @monitor_id: monitor ID to take screenshot from
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): a newly allocated string containing the
|
|
Packit |
a07778 |
* mime-type of the image format, or NULL upon error.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gchar *gvir_domain_screenshot(GVirDomain *dom,
|
|
Packit |
a07778 |
GVirStream *stream,
|
|
Packit |
a07778 |
guint monitor_id,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
virStreamPtr st = NULL;
|
|
Packit |
a07778 |
gchar *mime = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_STREAM(stream), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
g_object_get(stream, "handle", &st, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!(mime = virDomainScreenshot(priv->handle,
|
|
Packit |
a07778 |
st,
|
|
Packit |
a07778 |
monitor_id,
|
|
Packit |
a07778 |
flags))) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to take a screenshot");
|
|
Packit |
a07778 |
goto end;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
end:
|
|
Packit |
a07778 |
if (st != NULL)
|
|
Packit |
a07778 |
virStreamFree(st);
|
|
Packit |
a07778 |
return mime;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_open_console:
|
|
Packit |
a07778 |
* @dom: (transfer none): the domain
|
|
Packit |
a07778 |
* @devname: (transfer none)(allow-none): the device name
|
|
Packit |
a07778 |
* @stream: (transfer none): stream to use as output
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Open a text console for the domain @dom, connecting it to the
|
|
Packit |
a07778 |
* stream @stream. If @devname is NULL, the default console will
|
|
Packit |
a07778 |
* be opened, otherwise @devname can be used to specify a non-default
|
|
Packit |
a07778 |
* console device.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if the console was opened, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_open_console(GVirDomain *dom,
|
|
Packit |
a07778 |
GVirStream *stream,
|
|
Packit |
a07778 |
const gchar *devname,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
virStreamPtr st = NULL;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_STREAM(stream), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
g_object_get(stream, "handle", &st, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainOpenConsole(priv->handle,
|
|
Packit |
a07778 |
devname,
|
|
Packit |
a07778 |
st,
|
|
Packit |
a07778 |
flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to open console");
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
if (st != NULL)
|
|
Packit |
a07778 |
virStreamFree(st);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_open_graphics:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @idx: the graphics index
|
|
Packit |
a07778 |
* @fd: pre-opened socket pair
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Open a connection to the local graphics display, connecting it to the
|
|
Packit |
a07778 |
* socket pair file descriptor passed in as @fd.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if the graphics connection was opened, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_open_graphics(GVirDomain *dom,
|
|
Packit |
a07778 |
guint idx,
|
|
Packit |
a07778 |
int fd,
|
|
Packit |
a07778 |
unsigned int flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainOpenGraphics(priv->handle,
|
|
Packit |
a07778 |
idx,
|
|
Packit |
a07778 |
fd,
|
|
Packit |
a07778 |
flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to open graphics");
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_open_graphics_fd:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @idx: the graphics index
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This will create a socket pair connected to the graphics backend of @dom. One
|
|
Packit |
a07778 |
* end of the socket will be returned on success, and the other end is handed to
|
|
Packit |
a07778 |
* the hypervisor. If @dom has multiple graphics backends configured, then @idx
|
|
Packit |
a07778 |
* will determine which one is opened, starting from @idx 0.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: An fd on success, -1 on failure.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Since: 0.2.0
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
#if defined(HAVE_VIR_DOMAIN_OPEN_GRAPHICS_FD) || !defined(G_OS_WIN32)
|
|
Packit |
a07778 |
int gvir_domain_open_graphics_fd(GVirDomain *dom,
|
|
Packit |
a07778 |
guint idx,
|
|
Packit |
a07778 |
unsigned int flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
int ret = -1;
|
|
Packit |
a07778 |
#ifndef HAVE_VIR_DOMAIN_OPEN_GRAPHICS_FD
|
|
Packit |
a07778 |
int pair[2];
|
|
Packit |
a07778 |
#endif
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), -1);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, -1);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#ifdef HAVE_VIR_DOMAIN_OPEN_GRAPHICS_FD
|
|
Packit |
a07778 |
ret = virDomainOpenGraphicsFD(priv->handle, idx, flags);
|
|
Packit |
a07778 |
if (ret <= 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to open graphics");
|
|
Packit |
a07778 |
goto end;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
#else
|
|
Packit |
a07778 |
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) < 0) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to create socket pair");
|
|
Packit |
a07778 |
goto end;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainOpenGraphics(priv->handle, idx, pair[0], flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to open graphics");
|
|
Packit |
a07778 |
close(pair[0]);
|
|
Packit |
a07778 |
close(pair[1]);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
goto end;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
close(pair[0]);
|
|
Packit |
a07778 |
ret = pair[1];
|
|
Packit |
a07778 |
#endif
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
end:
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
#else
|
|
Packit |
a07778 |
int gvir_domain_open_graphics_fd(GVirDomain *dom G_GNUC_UNUSED,
|
|
Packit |
a07778 |
guint idx G_GNUC_UNUSED,
|
|
Packit |
a07778 |
unsigned int flags G_GNUC_UNUSED,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to create socketpair on this platform");
|
|
Packit |
a07778 |
return -1;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
#endif
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_suspend:
|
|
Packit |
a07778 |
* @dom: the domain to suspend
|
|
Packit |
a07778 |
* @err: Place-holder for possible errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Suspends an active domain, the process is frozen without further access to
|
|
Packit |
a07778 |
* CPU resources and I/O but the memory used by the domain at the hypervisor
|
|
Packit |
a07778 |
* level will stay allocated. Use gvir_domain_resume() to reactivate the domain.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain was suspended successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_suspend (GVirDomain *dom,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainSuspend(dom->priv->handle) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to suspend domain");
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_save:
|
|
Packit |
a07778 |
* @dom: the domain to save
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
Packit |
a07778 |
* @err: Place-holder for possible errors
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Saves the state of the domain on disk and stops it. Use #gvir_domain_start
|
|
Packit |
a07778 |
* to restore the saved state of the domain. A saved domain can be restored
|
|
Packit |
a07778 |
* even after shutdown/reboot of host machine.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain was saved successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_save (GVirDomain *dom,
|
|
Packit |
a07778 |
unsigned int flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainManagedSave(dom->priv->handle, flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to save domain");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_save_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(source_object);
|
|
Packit |
a07778 |
guint flags = GPOINTER_TO_UINT(task_data);
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_save(dom, flags, &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_domain_save_async:
|
|
Packit |
a07778 |
* @dom: the domain to save
|
|
Packit |
a07778 |
* @flags: extra flags, currently unused
|
|
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_domain_save.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_save_async (GVirDomain *dom,
|
|
Packit |
a07778 |
unsigned int flags,
|
|
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_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task, GUINT_TO_POINTER(flags), NULL);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_save_helper);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_save_finish:
|
|
Packit |
a07778 |
* @dom: the domain to save
|
|
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_domain_save_async.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain was saved successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_save_finish (GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_persistent:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if domain is persistent, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_get_persistent(GVirDomain *dom)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return virDomainIsPersistent(dom->priv->handle) == 1;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_saved:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if a stopped domain has a saved state to which it can be
|
|
Packit |
a07778 |
* restored to using #gvir_domain_start, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_get_saved(GVirDomain *dom)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return virDomainHasManagedSaveImage(dom->priv->handle, 0) == 1;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_devices:
|
|
Packit |
a07778 |
* @domain: the domain
|
|
Packit |
a07778 |
* @err: place-holder for possible errors, or NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Gets the list of devices attached to @domain. The returned list should
|
|
Packit |
a07778 |
* be freed with g_list_free(), after its elements have been unreffed with
|
|
Packit |
a07778 |
* g_object_unref().
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (element-type LibvirtGObject.DomainDevice) (transfer full): a newly
|
|
Packit |
a07778 |
* allocated #GList of #GVirDomainDevice.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_domain_get_devices(GVirDomain *domain,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirConfigDomain *config;
|
|
Packit |
a07778 |
GList *config_devices;
|
|
Packit |
a07778 |
GList *node;
|
|
Packit |
a07778 |
GList *ret = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(domain), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
config = gvir_domain_get_config(domain, 0, err);
|
|
Packit |
a07778 |
if (config == NULL)
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
config_devices = gvir_config_domain_get_devices(config);
|
|
Packit |
a07778 |
for (node = config_devices; node != NULL; node = node->next) {
|
|
Packit |
a07778 |
GVirConfigDomainDevice *device_config;
|
|
Packit |
a07778 |
GVirDomainDevice *device;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
device_config = GVIR_CONFIG_DOMAIN_DEVICE(node->data);
|
|
Packit |
a07778 |
device = gvir_domain_device_new(domain, device_config);
|
|
Packit |
a07778 |
if (device != NULL)
|
|
Packit |
a07778 |
ret = g_list_prepend(ret, device);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_unref (device_config);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_list_free (config_devices);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_list_reverse (ret);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_update_device:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @device: A modified device config
|
|
Packit |
a07778 |
* @flags: bitwise-OR of #GVirDomainUpdateDeviceFlags
|
|
Packit |
a07778 |
* @err: (allow-none):Place-holder for error or NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Update the configuration of a device.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE if device was updated successfully, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean
|
|
Packit |
a07778 |
gvir_domain_update_device(GVirDomain *dom,
|
|
Packit |
a07778 |
GVirConfigDomainDevice *device,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
gchar *xml;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DEVICE(device), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(device));
|
|
Packit |
a07778 |
g_return_val_if_fail(xml != NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (virDomainUpdateDeviceFlags(dom->priv->handle,
|
|
Packit |
a07778 |
xml, flags) < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to update device");
|
|
Packit |
a07778 |
g_free (xml);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free (xml);
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_create_snapshot:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): configuration of snapshot or NULL
|
|
Packit |
a07778 |
* @flags: bitwise-OR of #GVirDomainSnapshotCreateFlags
|
|
Packit |
a07778 |
* @err: (allow-none):Place-holder for error or NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): snapshot of domain. The returned object should be
|
|
Packit |
a07778 |
* unreffed when no longer needed
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomainSnapshot *
|
|
Packit |
a07778 |
gvir_domain_create_snapshot(GVirDomain *dom,
|
|
Packit |
a07778 |
GVirConfigDomainSnapshot *custom_conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
virDomainSnapshot *snapshot;
|
|
Packit |
a07778 |
GVirDomainSnapshot *dom_snapshot;
|
|
Packit |
a07778 |
gchar *custom_xml = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
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 |
if (!(snapshot = virDomainSnapshotCreateXML(priv->handle,
|
|
Packit |
a07778 |
custom_xml,
|
|
Packit |
a07778 |
flags))) {
|
|
Packit |
a07778 |
const gchar *domain_name = NULL;
|
|
Packit |
a07778 |
domain_name = gvir_domain_get_name(dom);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
gvir_set_error(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to create snapshot of %s", domain_name);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(custom_xml);
|
|
Packit |
a07778 |
return NULL;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
dom_snapshot = GVIR_DOMAIN_SNAPSHOT(g_object_new(GVIR_TYPE_DOMAIN_SNAPSHOT,
|
|
Packit |
a07778 |
"handle",
|
|
Packit |
a07778 |
snapshot,
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_free(custom_xml);
|
|
Packit |
a07778 |
return dom_snapshot;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void _create_snapshot_async_thread(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GError *error = NULL;
|
|
Packit |
a07778 |
GVirDomainSnapshot *snapshot;
|
|
Packit |
a07778 |
SnapshotCreateData *create_data = task_data;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
snapshot = gvir_domain_create_snapshot(source_object,
|
|
Packit |
a07778 |
create_data->snapshot_config,
|
|
Packit |
a07778 |
create_data->create_flags,
|
|
Packit |
a07778 |
&error);
|
|
Packit |
a07778 |
if (snapshot)
|
|
Packit |
a07778 |
g_task_return_pointer(task, snapshot, g_object_unref);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_error(task, error);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_create_snapshot_async:
|
|
Packit |
a07778 |
* @dom: The #GVirDomain
|
|
Packit |
a07778 |
* @custom_conf: (allow-none): Configuration of snapshot or %NULL
|
|
Packit |
a07778 |
* @flags: Bitwise-OR of #GVirDomainSnapshotCreateFlags
|
|
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_domain_create_snapshot_async(GVirDomain *dom,
|
|
Packit |
a07778 |
GVirConfigDomainSnapshot *custom_conf,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GAsyncReadyCallback callback,
|
|
Packit |
a07778 |
gpointer user_data)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
SnapshotCreateData *create_data;
|
|
Packit |
a07778 |
GTask *task;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_SNAPSHOT(custom_conf));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
create_data = g_slice_new(SnapshotCreateData);
|
|
Packit |
a07778 |
create_data->create_flags = flags;
|
|
Packit |
a07778 |
create_data->snapshot_config = g_object_ref (custom_conf);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(dom, cancellable, callback, user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task, create_data, (GDestroyNotify)snapshot_create_data_free);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, _create_snapshot_async_thread);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_create_snapshot_finish:
|
|
Packit |
a07778 |
* @domain: A #GVirDomain
|
|
Packit |
a07778 |
* @result: (transfer none): Async method result
|
|
Packit |
a07778 |
* @error: (allow-none): Error placeholder
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: (transfer full): The created snapshot
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GVirDomainSnapshot *gvir_domain_create_snapshot_finish(GVirDomain *domain,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **error)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, domain), NULL);
|
|
Packit |
a07778 |
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_pointer(G_TASK(result), error);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_fetch_snapshots:
|
|
Packit |
a07778 |
* @dom: The domain
|
|
Packit |
a07778 |
* @list_flags: bitwise-OR of #GVirDomainSnapshotListFlags
|
|
Packit |
a07778 |
* @cancellable: (allow-none) (transfer none): cancellation object
|
|
Packit |
a07778 |
* @error: (allow-none): Place-holder for error or %NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: %TRUE on success, %FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_fetch_snapshots(GVirDomain *dom,
|
|
Packit |
a07778 |
guint list_flags,
|
|
Packit |
a07778 |
GCancellable *cancellable,
|
|
Packit |
a07778 |
GError **error)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
virDomainSnapshotPtr *snapshots = NULL;
|
|
Packit |
a07778 |
GVirDomainSnapshot *snap;
|
|
Packit |
a07778 |
GHashTable *snap_table;
|
|
Packit |
a07778 |
int n_snaps = 0;
|
|
Packit |
a07778 |
int i;
|
|
Packit |
a07778 |
gboolean ret = FALSE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
snap_table = 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 |
n_snaps = virDomainListAllSnapshots(priv->handle, &snapshots, list_flags);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, error)) {
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (n_snaps < 0) {
|
|
Packit |
a07778 |
gvir_set_error(error, GVIR_DOMAIN_ERROR, 0,
|
|
Packit |
a07778 |
"Unable to fetch snapshots of %s",
|
|
Packit |
a07778 |
gvir_domain_get_name(dom));
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
for (i = 0; i < n_snaps; i ++) {
|
|
Packit |
a07778 |
if (g_cancellable_set_error_if_cancelled(cancellable, error)) {
|
|
Packit |
a07778 |
goto cleanup;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
snap = GVIR_DOMAIN_SNAPSHOT(g_object_new(GVIR_TYPE_DOMAIN_SNAPSHOT,
|
|
Packit |
a07778 |
"handle", snapshots[i],
|
|
Packit |
a07778 |
NULL));
|
|
Packit |
a07778 |
g_hash_table_insert(snap_table,
|
|
Packit |
a07778 |
(gpointer)gvir_domain_snapshot_get_name(snap),
|
|
Packit |
a07778 |
snap);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock(priv->lock);
|
|
Packit |
a07778 |
if (priv->snapshots != NULL)
|
|
Packit |
a07778 |
g_hash_table_unref(priv->snapshots);
|
|
Packit |
a07778 |
priv->snapshots = snap_table;
|
|
Packit |
a07778 |
snap_table = NULL;
|
|
Packit |
a07778 |
g_mutex_unlock(priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = TRUE;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
cleanup:
|
|
Packit |
a07778 |
free(snapshots);
|
|
Packit |
a07778 |
if (snap_table != NULL)
|
|
Packit |
a07778 |
g_hash_table_unref(snap_table);
|
|
Packit |
a07778 |
return ret;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_snapshots:
|
|
Packit |
a07778 |
* @dom: The domain
|
|
Packit |
a07778 |
* Returns: (element-type LibvirtGObject.DomainSnapshot) (transfer full): A
|
|
Packit |
a07778 |
* list of all the snapshots available for the given domain. The returned
|
|
Packit |
a07778 |
* list should be freed with g_list_free(), after its elements have been
|
|
Packit |
a07778 |
* unreffed with g_object_unref().
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
GList *gvir_domain_get_snapshots(GVirDomain *dom)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomainPrivate *priv;
|
|
Packit |
a07778 |
GList *snapshots = NULL;
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), NULL);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
priv = dom->priv;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_mutex_lock (priv->lock);
|
|
Packit |
a07778 |
if (dom->priv->snapshots != NULL) {
|
|
Packit |
a07778 |
snapshots = g_hash_table_get_values(priv->snapshots);
|
|
Packit |
a07778 |
g_list_foreach(snapshots, (GFunc)g_object_ref, NULL);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
g_mutex_unlock (priv->lock);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return snapshots;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void _fetch_snapshots_async_thread(GTask *task,
|
|
Packit |
a07778 |
gpointer source_object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GError *error = NULL;
|
|
Packit |
a07778 |
gboolean status;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
status = gvir_domain_fetch_snapshots(source_object,
|
|
Packit |
a07778 |
GPOINTER_TO_UINT(task_data),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
&error);
|
|
Packit |
a07778 |
if (status)
|
|
Packit |
a07778 |
g_task_return_boolean(task, TRUE);
|
|
Packit |
a07778 |
else
|
|
Packit |
a07778 |
g_task_return_error(task, error);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_fetch_snapshots_async:
|
|
Packit |
a07778 |
* @dom: The domain
|
|
Packit |
a07778 |
* @list_flags: bitwise-OR of #GVirDomainSnapshotListFlags
|
|
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_domain_fetch_snapshots_async(GVirDomain *dom,
|
|
Packit |
a07778 |
guint list_flags,
|
|
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_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(dom, cancellable, callback, user_data);
|
|
Packit |
a07778 |
g_task_set_task_data(task, GUINT_TO_POINTER(list_flags), NULL);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, _fetch_snapshots_async_thread);
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_fetch_snapshots_finish:
|
|
Packit |
a07778 |
* @dom: a #GVirDomain
|
|
Packit |
a07778 |
* @res: (transfer none): async method result
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: TRUE on success, FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_fetch_snapshots_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *res,
|
|
Packit |
a07778 |
GError **error)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(res, dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(res), error);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_get_has_current_snapshot:
|
|
Packit |
a07778 |
* @dom: a #GVirDomain
|
|
Packit |
a07778 |
* @flags: Unused, pass 0
|
|
Packit |
a07778 |
* @has_current_snapshot: (out): Will be set to %TRUE if the given domain
|
|
Packit |
a07778 |
* has a current snapshot and to %FALSE otherwise.
|
|
Packit |
a07778 |
* @error: (allow-none): Place-holder for error or %NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: %TRUE on success, %FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_get_has_current_snapshot(GVirDomain *dom,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
gboolean *has_current_snapshot,
|
|
Packit |
a07778 |
GError **error)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
int status;
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(has_current_snapshot != NULL, FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
status = virDomainHasCurrentSnapshot(dom->priv->handle,
|
|
Packit |
a07778 |
flags);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (status == -1) {
|
|
Packit |
a07778 |
gvir_set_error(error, GVIR_DOMAIN_ERROR, 0,
|
|
Packit |
a07778 |
"Unable to check if domain `%s' has a current snapshot",
|
|
Packit |
a07778 |
gvir_domain_get_name(dom));
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
*has_current_snapshot = status;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_set_time:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @date_time: (allow-none)(transfer none): the time to set as #GDateTime.
|
|
Packit |
a07778 |
* @flags: Unused, pass 0.
|
|
Packit |
a07778 |
* @err: (allow-none): Place-holder for error or %NULL
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* This function tries to set guest time to the given value. The passed
|
|
Packit |
a07778 |
* time must in UTC.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* If @date_time is %NULL, the time is reset using the domain's RTC.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Please note that some hypervisors may require guest agent to be configured
|
|
Packit |
a07778 |
* and running in order for this function to work.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: %TRUE on success, %FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_set_time(GVirDomain *dom,
|
|
Packit |
a07778 |
GDateTime *date_time,
|
|
Packit |
a07778 |
guint flags,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
int ret;
|
|
Packit |
a07778 |
GTimeVal tv;
|
|
Packit |
a07778 |
glong seconds;
|
|
Packit |
a07778 |
glong nseconds;
|
|
Packit |
a07778 |
guint settime_flags;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(flags == 0, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (date_time != NULL) {
|
|
Packit |
a07778 |
if (!g_date_time_to_timeval(date_time, &tv)) {
|
|
Packit |
a07778 |
g_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Failed to parse given time argument");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
seconds = tv.tv_sec;
|
|
Packit |
a07778 |
nseconds = tv.tv_usec * 1000;
|
|
Packit |
a07778 |
settime_flags = 0;
|
|
Packit |
a07778 |
} else {
|
|
Packit |
a07778 |
seconds = 0;
|
|
Packit |
a07778 |
nseconds = 0;
|
|
Packit |
a07778 |
settime_flags = VIR_DOMAIN_TIME_SYNC;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
ret = virDomainSetTime(dom->priv->handle, seconds, nseconds, settime_flags);
|
|
Packit |
a07778 |
if (ret < 0) {
|
|
Packit |
a07778 |
gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
|
|
Packit |
a07778 |
0,
|
|
Packit |
a07778 |
"Unable to set domain time");
|
|
Packit |
a07778 |
return FALSE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return TRUE;
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
static void
|
|
Packit |
a07778 |
gvir_domain_set_time_helper(GTask *task,
|
|
Packit |
a07778 |
gpointer object,
|
|
Packit |
a07778 |
gpointer task_data,
|
|
Packit |
a07778 |
GCancellable *cancellable G_GNUC_UNUSED)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
GVirDomain *dom = GVIR_DOMAIN(object);
|
|
Packit |
a07778 |
GDateTime *date_time = (GDateTime *) task_data;
|
|
Packit |
a07778 |
GError *err = NULL;
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
if (!gvir_domain_set_time(dom, date_time, 0, &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_domain_set_time_async:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
Packit |
a07778 |
* @date_time: (allow-none)(transfer none): the time to set as #GDateTime.
|
|
Packit |
a07778 |
* @flags: bitwise-OR of #GVirDomainSetTimeFlags.
|
|
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_domain_set_time.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
void gvir_domain_set_time_async(GVirDomain *dom,
|
|
Packit |
a07778 |
GDateTime *date_time,
|
|
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 |
|
|
Packit |
a07778 |
g_return_if_fail(GVIR_IS_DOMAIN(dom));
|
|
Packit |
a07778 |
g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
|
|
Packit |
a07778 |
g_return_if_fail(flags == 0);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
task = g_task_new(G_OBJECT(dom),
|
|
Packit |
a07778 |
cancellable,
|
|
Packit |
a07778 |
callback,
|
|
Packit |
a07778 |
user_data);
|
|
Packit |
a07778 |
if (date_time != NULL)
|
|
Packit |
a07778 |
g_task_set_task_data(task,
|
|
Packit |
a07778 |
g_date_time_ref(date_time),
|
|
Packit |
a07778 |
(GDestroyNotify)g_date_time_unref);
|
|
Packit |
a07778 |
g_task_run_in_thread(task, gvir_domain_set_time_helper);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
g_object_unref(task);
|
|
Packit |
a07778 |
}
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
/**
|
|
Packit |
a07778 |
* gvir_domain_set_time_finish:
|
|
Packit |
a07778 |
* @dom: the domain
|
|
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_domain_set_time_async.
|
|
Packit |
a07778 |
*
|
|
Packit |
a07778 |
* Returns: %TRUE on success, %FALSE otherwise.
|
|
Packit |
a07778 |
*/
|
|
Packit |
a07778 |
gboolean gvir_domain_set_time_finish(GVirDomain *dom,
|
|
Packit |
a07778 |
GAsyncResult *result,
|
|
Packit |
a07778 |
GError **err)
|
|
Packit |
a07778 |
{
|
|
Packit |
a07778 |
g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(g_task_is_valid(result, G_OBJECT(dom)), FALSE);
|
|
Packit |
a07778 |
g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
|
|
Packit |
a07778 |
|
|
Packit |
a07778 |
return g_task_propagate_boolean(G_TASK(result), err);
|
|
Packit |
a07778 |
}
|