[libvirt] Libvirt iSCSI APIs
by Ata Bohra
Hi All,
I am interested in extending libvirt APIs to support iSCSI operations such as: add/remove targets, list targets, list remote LUNs, rescan luns etc. The intention is to provide an interface that external programs can hook to manage iSCSI storage devices on a given hypervisor(I would be adding interfaces for ESX first). Looking at the libvirt.c interface for storage driver I'm unable find routines that can be overridden for specific hypervisor. Googling lead to a nice blog presentation that provisions VMs on remote LUN(s) for KVM but uses virish. (http://berrange.com/tags/iscsi/).
My question is; is this as per design not to expose iSCSI related APIs? Will an extention to libvirt.c (_virStorageDriver) so that every hypervisor can implement it is acceptable? Please correct me if I am missing something serious here.
Thanks!
Ata
12 years, 9 months
[libvirt] [glib PATCH V4] Add bindings for virDomainSave*()
by Jovanka Gulicoska
---
libvirt-gobject/libvirt-gobject-domain.c | 152 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 18 ++++
libvirt-gobject/libvirt-gobject.sym | 3 +
3 files changed, 173 insertions(+)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 088cd33..d803829 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -557,6 +557,158 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
}
/**
+ * gvir_domain_save_to_file:
+ * @dom: the domain
+ * @filename: path to the output file
+ * @custom_conf: configuration for domain or NULL
+ * @flags: the flags
+ *
+ * Returns: TRUE on success, FALSE otherwise
+ */
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err)
+{
+ GVirDomainPrivate *priv;
+ gchar *custom_xml = NULL;
+ int ret;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ priv = dom->priv;
+
+ if (flags || custom_conf != NULL) {
+ if (custom_conf != NULL)
+ custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
+
+ ret = virDomainSaveFlags(priv->handle, filename, custom_xml, flags);
+ g_free(custom_xml);
+ }
+ else {
+ ret = virDomainSave(priv->handle, filename);
+ }
+
+ if (ret < 0) {
+ gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
+ 0,
+ "Unable to save domain to file");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ gchar *filename;
+ gchar *custom_xml;
+ guint flags;
+} DomainSaveToFileData;
+
+static void domain_save_to_file_data_free(DomainSaveToFileData *data)
+{
+ g_free(data->filename);
+ g_free(data->custom_xml);
+ g_slice_free(DomainSaveToFileData, data);
+}
+
+static void
+gvir_domain_save_to_file_helper(GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable G_GNUC_UNUSED)
+{
+ GVirDomain *dom = GVIR_DOMAIN(object);
+ DomainSaveToFileData *data;
+ GVirConfigDomain *conf;
+ GError *err = NULL;
+
+ data = g_simple_async_result_get_op_res_gpointer(res);
+ conf = gvir_domain_get_config(dom, data->flags, &err);
+
+ if (!gvir_domain_save_to_file(dom, data->filename, conf, data->flags, &err))
+ g_simple_async_result_take_error(res, err);
+}
+
+/**
+ * gvir_domain_save_to_file_async:
+ * @dom: the domain
+ * @filename: path to output file
+ * @custom_conf: (allow-none): configuration for domain or NULL
+ * @flags: the flags
+ * @cancellable: (allow-none) (transfer none): cancallation object
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
+ *
+ * Asynchronous variant of #gvir_domain_save_to_file
+ */
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ DomainSaveToFileData *data;
+ gchar *xml = NULL;
+
+ g_return_if_fail(GVIR_IS_DOMAIN(dom));
+ g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
+
+ if (custom_xml != NULL)
+ xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
+
+ data = g_slice_new0(DomainSaveToFileData);
+ data->filename = g_strdup(filename);
+ data->custom_xml = g_strdup(xml);
+ data->flags = flags;
+
+ res = g_simple_async_result_new(G_OBJECT(dom),
+ callback,
+ user_data,
+ gvir_domain_save_to_file_async);
+ g_simple_async_result_set_op_res_gpointer(res, data, (GDestroyNotify)
+ domain_save_to_file_data_free);
+
+ g_simple_async_result_run_in_thread(res,
+ gvir_domain_save_to_file_helper,
+ G_PRIORITY_DEFAULT,
+ cancellable);
+
+ g_object_unref(res);
+}
+
+/**
+ * gvir_domain_save_to_file_finish:
+ * @dom: the domain to save
+ * @result: (transfer none): async method result
+ * @err: Place-holder for possible errors
+ *
+ * Finishes the operation started by #gvir_domain_save_to_file_async.
+ *
+ * Returns: TRUE if domain was saved successfully, FALSE otherwise.
+ */
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(g_simple_async_result_is_valid
+ (result,
+ G_OBJECT(dom),
+ gvir_domain_save_to_file_async), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ if (g_simple_async_result_propagate_error(G_SIMPLE_ASYNC_RESULT(result), err))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
* gvir_domain_get_config:
* @dom: the domain
* @flags: the flags
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 87b94f4..8f17799 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -148,6 +148,24 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
guint flags,
GError **err);
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err);
+
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err);
+
GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GError **err);
void gvir_domain_get_info_async(GVirDomain *dom,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 94e441a..54a093a 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -75,6 +75,9 @@ LIBVIRT_GOBJECT_0.0.8 {
gvir_domain_get_persistent;
gvir_domain_get_saved;
gvir_domain_screenshot;
+ gvir_domain_save_to_file;
+ gvir_domain_save_to_file_async;
+ gvir_domain_save_to_file_finish;
gvir_domain_snapshot_get_type;
gvir_domain_snapshot_handle_get_type;
--
1.7.10.4
12 years, 9 months
[libvirt] [PATCH] ARMHF: CPU Support for armhf.
by Chuck Short
Adding CPU encoder/decoder for armhf to avoid runtime error messages.
Signed-off-by: Chuck Short <chuck.short(a)canonical.com>
---
src/Makefile.am | 1 +
src/cpu/cpu.c | 2 ++
src/cpu/cpu_arm.c | 76
+++++++++++++++++++++++++++++++++++++++++++++++++++++ src/cpu/cpu_arm.h
| 32 ++++++++++++++++++++++ 4 files changed, 111 insertions(+)
create mode 100644 src/cpu/cpu_arm.c
create mode 100644 src/cpu/cpu_arm.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 6c3eaa7..bfe74d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -567,6 +567,7 @@ CPU_SOURCES
= \
cpu/cpu_generic.h cpu/cpu_generic.c \ cpu/cpu_x86.h
cpu/cpu_x86.c cpu/cpu_x86_data.h \ cpu/cpu_s390.h
cpu/cpu_s390.c \
+ cpu/cpu_arm.h cpu/cpu_arm.c \
cpu/cpu_map.h cpu/cpu_map.c cpu/cpu_powerpc.h \
cpu/cpu_powerpc.c
diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c
index 70a1da5..0ccbd4c 100644
--- a/src/cpu/cpu.c
+++ b/src/cpu/cpu.c
@@ -30,6 +30,7 @@
#include "cpu_x86.h"
#include "cpu_powerpc.h"
#include "cpu_s390.h"
+#include "cpu_arm.h"
#include "cpu_generic.h"
@@ -40,6 +41,7 @@ static struct cpuArchDriver *drivers[] = {
&cpuDriverX86,
&cpuDriverPowerPC,
&cpuDriverS390,
+ &cpuDriverArm,
/* generic driver must always be the last one */
&cpuDriverGeneric
};
diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c
new file mode 100644
index 0000000..fe97425
--- /dev/null
+++ b/src/cpu/cpu_arm.c
@@ -0,0 +1,76 @@
+
+/*
+ * cpu_arm.c: CPU driver for arm CPUs
+ *
+ * Copyright Canonical Ltd. 2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
+ *
+ * Authors:
+ * Chuck Short <chuck.short(a)canonical.com>
+ */
+
+#include <config.h>
+
+#include "memory.h"
+#include "cpu.h"
+
+#define VIR_FROM_THIS VIR_FROM_CPU
+
+static const char *archs[] = { "armv7l" };
+
+static union cpuData *
+ArmNodeData(void)
+{
+ union cpuData *data;
+
+ if (VIR_ALLOC(data) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ return data;
+}
+
+static int
+ArmDecode(virCPUDefPtr cpu ATTRIBUTE_UNUSED,
+ const union cpuData *data ATTRIBUTE_UNUSED,
+ const char **models ATTRIBUTE_UNUSED,
+ unsigned int nmodels ATTRIBUTE_UNUSED,
+ const char *preferred ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static void
+ArmDataFree(union cpuData *data)
+{
+ VIR_FREE(data);
+}
+
+struct cpuArchDriver cpuDriverArm = {
+ .name = "arm",
+ .arch = archs,
+ .narch = ARRAY_CARDINALITY(archs),
+ .compare = NULL,
+ .decode = ArmDecode,
+ .encode = NULL,
+ .free = ArmDataFree,
+ .nodeData = ArmNodeData,
+ .guestData = NULL,
+ .baseline = NULL,
+ .update = NULL,
+ .hasFeature = NULL,
+};
diff --git a/src/cpu/cpu_arm.h b/src/cpu/cpu_arm.h
new file mode 100644
index 0000000..4b7ddc5
--- /dev/null
+++ b/src/cpu/cpu_arm.h
@@ -0,0 +1,32 @@
+
+/*
+ * cpu_arm.h: CPU driver for arm CPUs
+ *
+ * Copyright Canonical Ltd. 2012
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
+ *
+ * Authors:
+ * Chuck Short <chuck.short(a)canonical.com>
+ */
+
+#ifndef __VIR_CPU_ARM_H__
+#define __VIR_CPU_ARM_H__
+
+#include "cpu.h"
+
+extern struct cpuArchDriver cpuDriverArm;
+
+#endif /* __VIR_CPU_ARM_H__ */
--
1.7.10.4
12 years, 9 months
[libvirt] [PATCH] Fix daemon auto-spawning
by Christophe Fergeau
Commit 32a9aac switched libvirt to use the XDG base directories
to locate most of its data/config. In particular, the per-user socket
for qemu:///session is now stored in the XDG runtime directory.
This directory is located by looking at the XDG_RUNTIME_DIR environment
variable, with a fallback to ~/.cache/libvirt if this variable is not
set.
When the daemon is autospawned because a client application wants
to use qemu:///session, the daemon is ran in a clean environment
which does not contain XDG_RUNTIME_DIR. It will create its socket
in ~/.cache/libvirt. If the client application has XDG_RUNTIME_DIR
set, it will not look for the socket in the fallback place, and will
fail to connect to the autospawned daemon.
This patch adds XDG_RUNTIME_DIR to the daemon environment before
auto-starting it. I've done this in virNetSocketForkDaemon rather
than in virCommandAddEnvPassCommon as I wasn't sure we want to pass
these variables to other commands libvirt spawns. XDG_CACHE_HOME
and XDG_CONFIG_HOME are also added to the daemon env as it makes use
of those as well.
---
src/rpc/virnetsocket.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 0b32ffe..08dfbb0 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -97,6 +97,9 @@ static int virNetSocketForkDaemon(const char *binary)
NULL);
virCommandAddEnvPassCommon(cmd);
+ virCommandAddEnvPass(cmd, "XDG_CACHE_HOME");
+ virCommandAddEnvPass(cmd, "XDG_CONFIG_HOME");
+ virCommandAddEnvPass(cmd, "XDG_RUNTIME_DIR");
virCommandClearCaps(cmd);
virCommandDaemonize(cmd);
ret = virCommandRun(cmd, NULL);
--
1.7.10.4
12 years, 9 months
[libvirt] dnsmasq SRV/TXT RR and Host xml parsing upgrade and bug fix
by Guannan Ren
The set of patches aims to three kind of jobs.
First, for SRV RR, in order to strictly comform to RFC 2782, the patch
changed and upgraded codes in following parts.
The format of SRV RR:
_Service._Proto.Name TTL Class SRV Priority Weight Port Target
1,The protocol and service labels are prepended with an underscore.
e.g: _ldap._tcp.example.com
2,The range of Port,Priority,Weight is 0-65535.
3,A Target of "." means that the service is decidedly not available at this domain.
Also, trying to invoke dnsmasq command line based on its manpage.
--srv-host=<_service>.<_prot>.[<domain>],[<target>[,<port>[,<priority>[,<weight>]]]]
_service and protocol are mandatory options.
The reset of them are optional.
When the target is not given in dnsmasq, it comform to the third item above.
For TXT RR, we changed the text field from mandatory to optional based on
dnsmasq manpage:
--txt-record=<name>[[,<text>],<text>]
Second, changed the way of dns element as well as its children elements parsing via
virXPathNodeSet(). It has advantages when multiple children elements there is.
Third, fixed related bug and unexposed bugs
https://bugzilla.redhat.com/show_bug.cgi?id=836326
12 years, 9 months
[libvirt] [PATCHv2] fix failure when building with --disable-debug
by Hu Tao
When building with --disable-debug, VIR_DEBUG expands to a nop.
But parameters to VIR_DEBUG can be variables that are passed only
to VIR_DEBUG. In the case the building system complains about unused
variables.
---
cfg.mk | 2 ++
src/util/logging.h | 8 +++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/cfg.mk b/cfg.mk
index 7664d5d..6e036fb 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -750,6 +750,8 @@ $(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protoco
$(MAKE) -C src remote/remote_client_bodies.h
# List all syntax-check exemptions:
+exclude_file_name_regexp--sc_avoid_attribute_unused_in_header = ^src/util/logging\.h$$
+
exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.c$$
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(command|util)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller
diff --git a/src/util/logging.h b/src/util/logging.h
index 70318d0..7cc5823 100644
--- a/src/util/logging.h
+++ b/src/util/logging.h
@@ -34,8 +34,14 @@
# define VIR_DEBUG_INT(category, f, l, ...) \
virLogMessage(category, VIR_LOG_DEBUG, f, l, 0, __VA_ARGS__)
# else
+/**
+ * virLogEatParam:
+ *
+ * Do nothing but eat parameters.
+ */
+static inline void virLogEatParam(void *unused ATTRIBUTE_UNUSED, ...) {}
# define VIR_DEBUG_INT(category, f, l, ...) \
- do { } while (0)
+ virLogEatParam((void*)category, f, l, __VA_ARGS__)
# endif /* !ENABLE_DEBUG */
# define VIR_INFO_INT(category, f, l, ...) \
--
1.7.10.2
12 years, 9 months
[libvirt] [PATCH 0/6] Add usb controller model="none"
by Peter Krempa
This series adds support for completely disabling USB bus for a host if a user
requires this. For this to work a new USB controller model "none" was added
that removes the USB bus.
The controller is added in patches 2-4. Patch 1 cleans up some nits (and is not
necessary) and patches 5 and 6 tweak qemuxml2argvtest and add tests to check the
new controller.
Peter Krempa (6):
maint: Clean up coding style
domain_conf: Add USB controler model "none"
domain_conf: Add helpers to verify if device configuration is valid
qemu: Add support for "none" USB controller
tests: Add support for cathing domain XML parsing errors
tests: Add tests to check the new USB "none" controller
docs/schemas/domaincommon.rng | 1 +
src/conf/domain_conf.c | 121 +++++-
src/conf/domain_conf.h | 6 +
src/libvirt_private.syms | 2 +
src/qemu/qemu_command.c | 29 +-
src/qemu/qemu_driver.c | 13 +-
.../qemuxml2argvdata/qemuxml2argv-usb-none-hub.xml | 19 +
.../qemuxml2argv-usb-none-other.xml | 19 +
.../qemuxml2argv-usb-none-usbtablet.xml | 21 +
tests/qemuxml2argvdata/qemuxml2argv-usb-none.args | 5 +
tests/qemuxml2argvdata/qemuxml2argv-usb-none.xml | 16 +
tests/qemuxml2argvtest.c | 507 ++++++++++----------
12 files changed, 491 insertions(+), 268 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-none-hub.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-none-other.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-none-usbtablet.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-none.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-none.xml
--
1.7.8.6
12 years, 9 months
[libvirt] [PATCH] Fix directory removal in virStorageBackendFileSystemVolDelete
by Sascha Peilicke
---
src/storage/storage_backend_fs.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 4894994..8e93aaa 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1138,6 +1138,17 @@ virStorageBackendFileSystemVolDelete(virConnectPtr conn ATTRIBUTE_UNUSED,
virCheckFlags(0, -1);
if (unlink(vol->target.path) < 0) {
+ if (errno == EISDIR /* linux */ ||
+ errno == EPERM /* posix */) {
+ if (rmdir(vol->target.path) < 0) {
+ virReportSystemError(errno,
+ _("cannot remove directory '%s'"),
+ vol->target.path);
+ return -1;
+ } else {
+ return 0;
+ }
+ }
/* Silently ignore failures where the vol has already gone away */
if (errno != ENOENT) {
virReportSystemError(errno,
--
1.7.10.4
12 years, 9 months
[libvirt] [RFC] [PATCH 1/5] add configure option --with-fuse for libvirt
by Gao feng
add a configure option --with-fuse to prepare introduction
of fuse support for libvirt lxc.
Signed-off-by: Gao feng <gaofeng(a)cn.fujitsu.com>
---
configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
libvirt.spec.in | 9 +++++++++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index d45f4f1..d5cf45f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1694,7 +1694,47 @@ AM_CONDITIONAL([HAVE_CAPNG], [test "$with_capng" != "no"])
AC_SUBST([CAPNG_CFLAGS])
AC_SUBST([CAPNG_LIBS])
+dnl libfuse
+AC_ARG_WITH([fuse],
+ AC_HELP_STRING([--with-fuse], [use libfuse to proivde fuse filesystem support for libvirt lxc]),
+ [],
+ [with_fuse=check])
+dnl
+dnl This check looks for 'fuse'
+dnl
+FUSE_CFLAGS=
+FUSE_LIBS=
+if test "$with_fuse" != "no"; then
+ old_cflags="$CFLAGS"
+ old_libs="$LIBS"
+ old_cppflags="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64"
+ if test "$with_fuse" = "check"; then
+ AC_CHECK_HEADER([fuse.h], [], [with_fuse=no])
+ AC_CHECK_LIB([fuse], [fuse_main], [], [with_fuse=no])
+ if test "$with_fuse" != "no"; then
+ with_fuse="yes"
+ fi
+ else
+ fail=0
+ AC_CHECK_HEADER([fuse.h], [], [fail=1])
+ AC_CHECK_LIB([fuse], [fuse_main], [], [fail=1])
+ test $fail = 1 &&
+ AC_MSG_ERROR([You must install the fuse >= 2.9.0 development package in order to compile and run libvirt])
+ fi
+ CFLAGS="$old_cflags"
+ LIBS="$old_libs"
+ CPPFLAGS="$old_cppflags"
+fi
+if test "$with_fuse" = "yes"; then
+ FUSE_LIBS="-lfuse"
+ FUSE_CFLAGS="-D_FILE_OFFSET_BITS=64"
+ AC_DEFINE_UNQUOTED([HAVE_FUSE], 1, [Whether fuse is available for privilege reduction])
+fi
+AM_CONDITIONAL([HAVE_FUSE], [test "$with_fuse" != "no"])
+AC_SUBST([FUSE_CFLAGS])
+AC_SUBST([FUSE_LIBS])
dnl virsh libraries
AC_CHECK_HEADERS([readline/readline.h])
@@ -2912,6 +2952,11 @@ AC_MSG_NOTICE([ capng: $CAPNG_CFLAGS $CAPNG_LIBS])
else
AC_MSG_NOTICE([ capng: no])
fi
+if test "$with_fuse" = "yes" ; then
+AC_MSG_NOTICE([ fuse: $FUSE_CFLAGS $FUSE_LIBS])
+else
+AC_MSG_NOTICE([ fuse: no])
+fi
if test "$with_xen" = "yes" ; then
AC_MSG_NOTICE([ xen: $XEN_CFLAGS $XEN_LIBS])
else
diff --git a/libvirt.spec.in b/libvirt.spec.in
index ec2b3b4..8cb2291 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -86,6 +86,7 @@
# A few optional bits off by default, we enable later
%define with_polkit 0%{!?_without_polkit:0}
%define with_capng 0%{!?_without_capng:0}
+%define with_fuse 0%{!?_without_fuse:0}
%define with_netcf 0%{!?_without_netcf:0}
%define with_udev 0%{!?_without_udev:0}
%define with_hal 0%{!?_without_hal:0}
@@ -450,6 +451,9 @@ BuildRequires: numactl-devel
%if %{with_capng}
BuildRequires: libcap-ng-devel >= 0.5.0
%endif
+%if %{with_fuse}
+BuildRequires: fuse-devel >= 2.9.0
+%endif
%if %{with_phyp}
BuildRequires: libssh2-devel
%endif
@@ -1092,6 +1096,10 @@ of recent versions of Linux (and other OSes).
%define _without_capng --without-capng
%endif
+%if ! %{with_fuse}
+%define _without_fuse --without-fuse
+%endif
+
%if ! %{with_netcf}
%define _without_netcf --without-netcf
%endif
@@ -1181,6 +1189,7 @@ autoreconf -if
%{?_without_numactl} \
%{?_without_numad} \
%{?_without_capng} \
+ %{?_without_fuse} \
%{?_without_netcf} \
%{?_without_selinux} \
%{?_without_hal} \
--
1.7.7.6
12 years, 9 months
[libvirt] [glib PATCH V3] Add bindings for virDomainSave*()
by Jovanka Gulicoska
---
libvirt-gobject/libvirt-gobject-domain.c | 145 ++++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 18 ++++
libvirt-gobject/libvirt-gobject.sym | 3 +
3 files changed, 166 insertions(+)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 088cd33..d9688f7 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -557,6 +557,151 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
}
/**
+ * gvir_domain_save_to_file:
+ * @dom: the domain
+ * @filename: path to the output file
+ * @custom_conf: configuration for domain or NULL
+ * @flags: the flags
+ *
+ * Returns: TRUE on success, FALSE otherwise
+ */
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err)
+{
+ GVirDomainPrivate *priv;
+ gchar *custom_xml;
+ int ret;
+
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ priv = dom->priv;
+
+ if (flags || (custom_conf != NULL)) {
+ custom_xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
+ ret = virDomainSaveFlags(priv->handle, filename, custom_xml, flags);
+ g_free (custom_xml);
+ }
+ else
+ ret = virDomainSave(priv->handle, filename);
+
+ if (ret < 0) {
+ gvir_set_error_literal(err, GVIR_DOMAIN_ERROR,
+ 0,
+ "Unable to save domain to file");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ gchar *filename;
+ gchar *custom_xml;
+ guint flags;
+} DomainSaveToFileData;
+
+static void domain_save_to_file_data_free(DomainSaveToFileData *data)
+{
+ g_free(data->filename);
+ g_free(data->custom_xml);
+ g_slice_free(DomainSaveToFileData, data);
+}
+
+static void
+gvir_domain_save_to_file_helper(GSimpleAsyncResult *res,
+ GObject *object,
+ GCancellable *cancellable G_GNUC_UNUSED)
+{
+ GVirDomain *dom = GVIR_DOMAIN(object);
+ DomainSaveToFileData *data;
+ GVirConfigDomain *conf;
+ GError *err = NULL;
+
+ data = g_simple_async_result_get_op_res_gpointer(res);
+ conf = gvir_domain_get_config(dom, data->flags, &err);
+
+ if (!gvir_domain_save_to_file(dom, data->filename, conf, data->flags, &err))
+ g_simple_async_result_take_error(res, err);
+}
+
+/**
+ * gvir_domain_save_to_file_async:
+ * @dom: the domain
+ * @filename: path to output file
+ * @custom_conf: configuration for domain
+ * @flags: the flags
+ * @cancellable: cancallation object
+ * @callback: (scope async): completion callback
+ * @user_data: (closure): opaque data for callback
+ *
+ * Asynchronous variant of #gvir_domain_save_to_file
+ */
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res;
+ DomainSaveToFileData *data;
+ gchar *xml;
+
+ g_return_if_fail(GVIR_IS_DOMAIN(dom));
+ g_return_if_fail(GVIR_CONFIG_IS_DOMAIN (custom_conf));
+ g_return_if_fail((cancellable == NULL) || G_IS_CANCELLABLE(cancellable));
+
+ xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(custom_conf));
+
+ data = g_slice_new0(DomainSaveToFileData);
+ data->filename = g_strdup(filename);
+ data->custom_xml = g_strdup(xml);
+ data->flags = flags;
+
+ res = g_simple_async_result_new(G_OBJECT(dom),
+ callback,
+ user_data,
+ gvir_domain_save_to_file_async);
+ g_simple_async_result_set_op_res_gpointer(res, data, (GDestroyNotify)domain_save_to_file_data_free);
+
+ g_simple_async_result_run_in_thread(res,
+ gvir_domain_save_to_file_helper,
+ G_PRIORITY_DEFAULT,
+ cancellable);
+
+ g_object_unref(res);
+}
+
+/**
+ * gvir_domain_save_to_file_finish:
+ * @dom: the domain to save
+ * @result: (transfer none): async method result
+ * @err: Place-holder for possible errors
+ *
+ * Finishes the operation started by #gvir_domain_save_to_file_async.
+ *
+ * Returns: TRUE if domain was saved successfully, FALSE otherwise.
+ */
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+ g_return_val_if_fail(g_simple_async_result_is_valid(result, G_OBJECT(dom), gvir_domain_save_to_file_async), FALSE);
+ g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+
+ if (g_simple_async_result_propagate_error(G_SIMPLE_ASYNC_RESULT(result), err))
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
* gvir_domain_get_config:
* @dom: the domain
* @flags: the flags
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index 87b94f4..8f17799 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -148,6 +148,24 @@ gboolean gvir_domain_reboot(GVirDomain *dom,
guint flags,
GError **err);
+gboolean gvir_domain_save_to_file(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GError **err);
+
+void gvir_domain_save_to_file_async(GVirDomain *dom,
+ gchar *filename,
+ GVirConfigDomain *custom_conf,
+ guint flags,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean gvir_domain_save_to_file_finish(GVirDomain *dom,
+ GAsyncResult *result,
+ GError **err);
+
GVirDomainInfo *gvir_domain_get_info(GVirDomain *dom,
GError **err);
void gvir_domain_get_info_async(GVirDomain *dom,
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 94e441a..c6b0c28 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -75,6 +75,9 @@ LIBVIRT_GOBJECT_0.0.8 {
gvir_domain_get_persistent;
gvir_domain_get_saved;
gvir_domain_screenshot;
+ gvir_domain_save_to_file;
+ gvir_domain_save_to_file_async;
+ gvir_domain_save_to_file_finish;
gvir_domain_snapshot_get_type;
gvir_domain_snapshot_handle_get_type;
--
1.7.10.4
12 years, 9 months