Introduce a src/libvirt-domain-snapshot.c file to hold all the
methods related to the virDomainSnapshot type.
---
docs/apibuild.py | 1 +
po/POTFILES.in | 1 +
src/Makefile.am | 2 +
src/datatypes.h | 1 +
src/libvirt-domain-snapshot.c | 1222 +++++++++++++++++++++++++++++++++++++++++
src/libvirt.c | 1194 ----------------------------------------
6 files changed, 1227 insertions(+), 1194 deletions(-)
create mode 100644 src/libvirt-domain-snapshot.c
diff --git a/docs/apibuild.py b/docs/apibuild.py
index 30e224d..b5bd936 100755
--- a/docs/apibuild.py
+++ b/docs/apibuild.py
@@ -24,6 +24,7 @@ included_files = {
"libvirt.h": "header with general libvirt API definitions",
"virterror.h": "header with error specific API definitions",
"libvirt.c": "Main interfaces for the libvirt library",
+ "libvirt-domain-snapshot.c": "Domain snapshot interfaces for the libvirt
library",
"virerror.c": "implements error handling and reporting code for
libvirt",
"virevent.c": "event loop for monitoring file handles",
"virtypedparam.c": "virTypedParameters APIs",
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 59be2e6..6f88a15 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -57,6 +57,7 @@ src/interface/interface_backend_netcf.c
src/interface/interface_backend_udev.c
src/internal.h
src/libvirt.c
+src/libvirt-domain-snapshot.c
src/libvirt-lxc.c
src/libvirt-qemu.c
src/locking/lock_daemon.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7521bde..1b0a97d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -189,6 +189,7 @@ DRIVER_SOURCES = \
fdstream.c fdstream.h \
$(NODE_INFO_SOURCES) \
libvirt.c libvirt_internal.h \
+ libvirt-domain-snapshot.c \
locking/lock_manager.c locking/lock_manager.h \
locking/lock_driver.h \
locking/lock_driver_nop.h locking/lock_driver_nop.c \
@@ -2186,6 +2187,7 @@ libvirt_setuid_rpc_client_la_SOURCES = \
remote/lxc_protocol.c \
datatypes.c \
libvirt.c \
+ libvirt-domain-snapshot.c \
libvirt-lxc.c \
$(NULL)
diff --git a/src/datatypes.h b/src/datatypes.h
index 5868ce3..1d6c382 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -27,6 +27,7 @@
# include "driver.h"
# include "virthread.h"
# include "virobject.h"
+# include "viruuid.h"
extern virClassPtr virConnectClass;
extern virClassPtr virDomainClass;
diff --git a/src/libvirt-domain-snapshot.c b/src/libvirt-domain-snapshot.c
new file mode 100644
index 0000000..3b41a37
--- /dev/null
+++ b/src/libvirt-domain-snapshot.c
@@ -0,0 +1,1222 @@
+/*
+ * libvirt-domain-snapshot.c: entry points for virDomainSnapshotPtr APIs
+ *
+ * Copyright (C) 2006-2014 Red Hat, Inc.
+ *
+ * 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, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "datatypes.h"
+#include "virlog.h"
+
+VIR_LOG_INIT("libvirt.domain-snapshot");
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+/**
+ * virDomainSnapshotGetName:
+ * @snapshot: a snapshot object
+ *
+ * Get the public name for that snapshot
+ *
+ * Returns a pointer to the name or NULL, the string need not be deallocated
+ * as its lifetime will be the same as the snapshot object.
+ */
+const char *
+virDomainSnapshotGetName(virDomainSnapshotPtr snapshot)
+{
+ VIR_DEBUG("snapshot=%p", snapshot);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, NULL);
+
+ return snapshot->name;
+}
+
+
+/**
+ * virDomainSnapshotGetDomain:
+ * @snapshot: a snapshot object
+ *
+ * Provides the domain pointer associated with a snapshot. The
+ * reference counter on the domain is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do not use this
+ * function. Instead, store the domain and the snapshot object together.
+ *
+ * Returns the domain or NULL.
+ */
+virDomainPtr
+virDomainSnapshotGetDomain(virDomainSnapshotPtr snapshot)
+{
+ VIR_DEBUG("snapshot=%p", snapshot);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, NULL);
+
+ return snapshot->domain;
+}
+
+
+/**
+ * virDomainSnapshotGetConnect:
+ * @snapshot: a snapshot object
+ *
+ * Provides the connection pointer associated with a snapshot. The
+ * reference counter on the connection is not increased by this
+ * call.
+ *
+ * WARNING: When writing libvirt bindings in other languages, do not use this
+ * function. Instead, store the connection and the snapshot object together.
+ *
+ * Returns the connection or NULL.
+ */
+virConnectPtr
+virDomainSnapshotGetConnect(virDomainSnapshotPtr snapshot)
+{
+ VIR_DEBUG("snapshot=%p", snapshot);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, NULL);
+
+ return snapshot->domain->conn;
+}
+
+
+/**
+ * virDomainSnapshotCreateXML:
+ * @domain: a domain object
+ * @xmlDesc: string containing an XML description of the domain
+ * @flags: bitwise-OR of virDomainSnapshotCreateFlags
+ *
+ * Creates a new snapshot of a domain based on the snapshot xml
+ * contained in xmlDesc.
+ *
+ * If @flags is 0, the domain can be active, in which case the
+ * snapshot will be a system checkpoint (both disk state and runtime
+ * VM state such as RAM contents), where reverting to the snapshot is
+ * the same as resuming from hibernation (TCP connections may have
+ * timed out, but everything else picks up where it left off); or
+ * the domain can be inactive, in which case the snapshot includes
+ * just the disk state prior to booting. The newly created snapshot
+ * becomes current (see virDomainSnapshotCurrent()), and is a child
+ * of any previous current snapshot.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE, then this
+ * is a request to reinstate snapshot metadata that was previously
+ * discarded, rather than creating a new snapshot. This can be used
+ * to recreate a snapshot hierarchy on a destination, then remove it
+ * on the source, in order to allow migration (since migration
+ * normally fails if snapshot metadata still remains on the source
+ * machine). When redefining snapshot metadata, the current snapshot
+ * will not be altered unless the VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
+ * flag is also present. It is an error to request the
+ * VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT flag without
+ * VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE. On some hypervisors,
+ * redefining an existing snapshot can be used to alter host-specific
+ * portions of the domain XML to be used during revert (such as
+ * backing filenames associated with disk devices), but must not alter
+ * guest-visible layout. When redefining a snapshot name that does
+ * not exist, the hypervisor may validate that reverting to the
+ * snapshot appears to be possible (for example, disk images have
+ * snapshot contents by the requested name). Not all hypervisors
+ * support these flags.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, then the
+ * domain's disk images are modified according to @xmlDesc, but then
+ * the just-created snapshot has its metadata deleted. This flag is
+ * incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_HALT, then the domain
+ * will be inactive after the snapshot completes, regardless of whether
+ * it was active before; otherwise, a running domain will still be
+ * running after the snapshot. This flag is invalid on transient domains,
+ * and is incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, then the domain
+ * is not paused while creating the snapshot. This increases the size
+ * of the memory dump file, but reduces downtime of the guest while
+ * taking the snapshot. Some hypervisors only support this flag during
+ * external checkpoints.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY, then the
+ * snapshot will be limited to the disks described in @xmlDesc, and no
+ * VM state will be saved. For an active guest, the disk image may be
+ * inconsistent (as if power had been pulled), and specifying this
+ * with the VIR_DOMAIN_SNAPSHOT_CREATE_HALT flag risks data loss.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, then the
+ * libvirt will attempt to use guest agent to freeze and thaw all
+ * file systems in use within domain OS. However, if the guest agent
+ * is not present, an error is thrown. Moreover, this flag requires
+ * VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY to be passed as well.
+ *
+ * By default, if the snapshot involves external files, and any of the
+ * destination files already exist as a non-empty regular file, the
+ * snapshot is rejected to avoid losing contents of those files.
+ * However, if @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT,
+ * then the destination files must be pre-created manually with
+ * the correct image format and metadata including backing store path
+ * (this allows a management app to pre-create files with relative backing
+ * file names, rather than the default of creating with absolute backing
+ * file names). Note that setting incorrect metadata in the pre-created
+ * image may lead to the VM being unable to start.
+ *
+ * Be aware that although libvirt prefers to report errors up front with
+ * no other effect, some hypervisors have certain types of failures where
+ * the overall command can easily fail even though the guest configuration
+ * was partially altered (for example, if a disk snapshot request for two
+ * disks fails on the second disk, but the first disk alteration cannot be
+ * rolled back). If this API call fails, it is therefore normally
+ * necessary to follow up with virDomainGetXMLDesc() and check each disk
+ * to determine if any partial changes occurred. However, if @flags
+ * contains VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC, then libvirt guarantees
+ * that this command will not alter any disks unless the entire set of
+ * changes can be done atomically, making failure recovery simpler (note
+ * that it is still possible to fail after disks have changed, but only
+ * in the much rarer cases of running out of memory or disk space).
+ *
+ * Some hypervisors may prevent this operation if there is a current
+ * block copy operation; in that case, use virDomainBlockJobAbort()
+ * to stop the block copy first.
+ *
+ * virDomainSnapshotFree should be used to free the resources after the
+ * snapshot object is no longer needed.
+ *
+ * Returns an (opaque) virDomainSnapshotPtr on success, NULL on failure.
+ */
+virDomainSnapshotPtr
+virDomainSnapshotCreateXML(virDomainPtr domain,
+ const char *xmlDesc,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "xmlDesc=%s, flags=%x", xmlDesc, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(xmlDesc, error);
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) &&
+ !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
+ virReportInvalidArg(flags,
+ _("use of 'current' flag in %s requires "
+ "'redefine' flag"),
+ __FUNCTION__);
+ goto error;
+ }
+ if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
+ (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
+ virReportInvalidArg(flags,
+ _("'redefine' and 'no metadata' flags in
%s are "
+ "mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+ if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
+ (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
+ virReportInvalidArg(flags,
+ _("'redefine' and 'halt' flags in %s are
mutually "
+ "exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainSnapshotCreateXML) {
+ virDomainSnapshotPtr ret;
+ ret = conn->driver->domainSnapshotCreateXML(domain, xmlDesc, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainSnapshotGetXMLDesc:
+ * @snapshot: a domain snapshot object
+ * @flags: bitwise-OR of subset of virDomainXMLFlags
+ *
+ * Provide an XML description of the domain snapshot.
+ *
+ * No security-sensitive data will be included unless @flags contains
+ * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
+ * connections. For this API, @flags should not contain either
+ * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ * the caller must free() the returned value.
+ */
+char *
+virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, NULL);
+ conn = snapshot->domain->conn;
+
+ if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
+ virReportError(VIR_ERR_OPERATION_DENIED, "%s",
+ _("virDomainSnapshotGetXMLDesc with secure flag"));
+ goto error;
+ }
+
+ if (conn->driver->domainSnapshotGetXMLDesc) {
+ char *ret;
+ ret = conn->driver->domainSnapshotGetXMLDesc(snapshot, flags);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainSnapshotNum:
+ * @domain: a domain object
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Provides the number of domain snapshots for this domain.
+ *
+ * By default, this command covers all snapshots; it is also possible to
+ * limit things to just snapshots with no parents, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Returns the number of domain snapshots found or -1 in case of error.
+ */
+int
+virDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+
+ conn = domain->conn;
+ if (conn->driver->domainSnapshotNum) {
+ int ret = conn->driver->domainSnapshotNum(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotListNames:
+ * @domain: a domain object
+ * @names: array to collect the list of names of snapshots
+ * @nameslen: size of @names
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Collect the list of domain snapshots for the given domain, and store
+ * their names in @names. The value to use for @nameslen can be determined
+ * by virDomainSnapshotNum() with the same @flags.
+ *
+ * By default, this command covers all snapshots; it is also possible to
+ * limit things to just snapshots with no parents, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Note that this command is inherently racy: another connection can
+ * define a new snapshot between a call to virDomainSnapshotNum() and
+ * this call. You are only guaranteed that all currently defined
+ * snapshots were listed if the return is less than @nameslen. Likewise,
+ * you should be prepared for virDomainSnapshotLookupByName() to fail when
+ * converting a name from this call into a snapshot object, if another
+ * connection deletes the snapshot in the meantime. For more control over
+ * the results, see virDomainListAllSnapshots().
+ *
+ * Returns the number of domain snapshots found or -1 in case of error.
+ * The caller is responsible to call free() for each member of the array.
+ */
+int
+virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "names=%p, nameslen=%d, flags=%x",
+ names, nameslen, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(names, error);
+ virCheckNonNegativeArgGoto(nameslen, error);
+
+ if (conn->driver->domainSnapshotListNames) {
+ int ret = conn->driver->domainSnapshotListNames(domain, names,
+ nameslen, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainListAllSnapshots:
+ * @domain: a domain object
+ * @snaps: pointer to variable to store the array containing snapshot objects,
+ * or NULL if the list is not required (just returns number of
+ * snapshots)
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Collect the list of domain snapshots for the given domain, and allocate
+ * an array to store those objects. This API solves the race inherent in
+ * virDomainSnapshotListNames().
+ *
+ * By default, this command covers all snapshots; it is also possible to
+ * limit things to just snapshots with no parents, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Returns the number of domain snapshots found or -1 and sets @snaps to
+ * NULL in case of error. On success, the array stored into @snaps is
+ * guaranteed to have an extra allocated element set to NULL but not included
+ * in the return count, to make iteration easier. The caller is responsible
+ * for calling virDomainSnapshotFree() on each array element, then calling
+ * free() on @snaps.
+ */
+int
+virDomainListAllSnapshots(virDomainPtr domain, virDomainSnapshotPtr **snaps,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "snaps=%p, flags=%x", snaps, flags);
+
+ virResetLastError();
+
+ if (snaps)
+ *snaps = NULL;
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ if (conn->driver->domainListAllSnapshots) {
+ int ret = conn->driver->domainListAllSnapshots(domain, snaps, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotNumChildren:
+ * @snapshot: a domain snapshot object
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Provides the number of child snapshots for this domain snapshot.
+ *
+ * By default, this command covers only direct children; it is also possible
+ * to expand things to cover all descendants, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Returns the number of domain snapshots found or -1 in case of error.
+ */
+int
+virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ if (conn->driver->domainSnapshotNumChildren) {
+ int ret = conn->driver->domainSnapshotNumChildren(snapshot, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotListChildrenNames:
+ * @snapshot: a domain snapshot object
+ * @names: array to collect the list of names of snapshots
+ * @nameslen: size of @names
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Collect the list of domain snapshots that are children of the given
+ * snapshot, and store their names in @names. The value to use for
+ * @nameslen can be determined by virDomainSnapshotNumChildren() with
+ * the same @flags.
+ *
+ * By default, this command covers only direct children; it is also possible
+ * to expand things to cover all descendants, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Returns the number of domain snapshots found or -1 in case of error.
+ * Note that this command is inherently racy: another connection can
+ * define a new snapshot between a call to virDomainSnapshotNumChildren()
+ * and this call. You are only guaranteed that all currently defined
+ * snapshots were listed if the return is less than @nameslen. Likewise,
+ * you should be prepared for virDomainSnapshotLookupByName() to fail when
+ * converting a name from this call into a snapshot object, if another
+ * connection deletes the snapshot in the meantime. For more control over
+ * the results, see virDomainSnapshotListAllChildren().
+ *
+ * Returns the number of domain snapshots found or -1 in case of error.
+ * The caller is responsible to call free() for each member of the array.
+ */
+int
+virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
+ char **names, int nameslen,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, names=%p, nameslen=%d, flags=%x",
+ snapshot, names, nameslen, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ virCheckNonNullArgGoto(names, error);
+ virCheckNonNegativeArgGoto(nameslen, error);
+
+ if (conn->driver->domainSnapshotListChildrenNames) {
+ int ret = conn->driver->domainSnapshotListChildrenNames(snapshot,
+ names,
+ nameslen,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotListAllChildren:
+ * @snapshot: a domain snapshot object
+ * @snaps: pointer to variable to store the array containing snapshot objects,
+ * or NULL if the list is not required (just returns number of
+ * snapshots)
+ * @flags: bitwise-OR of supported virDomainSnapshotListFlags
+ *
+ * Collect the list of domain snapshots that are children of the given
+ * snapshot, and allocate an array to store those objects. This API solves
+ * the race inherent in virDomainSnapshotListChildrenNames().
+ *
+ * By default, this command covers only direct children; it is also possible
+ * to expand things to cover all descendants, when @flags includes
+ * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
+ * groups, where each group contains bits that describe mutually exclusive
+ * attributes of a snapshot, and where all bits within a group describe
+ * all possible snapshots. Some hypervisors might reject explicit bits
+ * from a group where the hypervisor cannot make a distinction. For a
+ * group supported by a given hypervisor, the behavior when no bits of a
+ * group are set is identical to the behavior when all bits in that group
+ * are set. When setting bits from more than one group, it is possible to
+ * select an impossible combination, in that case a hypervisor may return
+ * either 0 or an error.
+ *
+ * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
+ * have no further children (a leaf snapshot).
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
+ * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
+ * whether they have metadata that would prevent the removal of the last
+ * reference to a domain.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
+ * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
+ * for filtering snapshots based on what domain state is tracked by the
+ * snapshot.
+ *
+ * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
+ * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
+ * whether the snapshot is stored inside the disk images or as
+ * additional files.
+ *
+ * Returns the number of domain snapshots found or -1 and sets @snaps to
+ * NULL in case of error. On success, the array stored into @snaps is
+ * guaranteed to have an extra allocated element set to NULL but not included
+ * in the return count, to make iteration easier. The caller is responsible
+ * for calling virDomainSnapshotFree() on each array element, then calling
+ * free() on @snaps.
+ */
+int
+virDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
+ virDomainSnapshotPtr **snaps,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, snaps=%p, flags=%x", snapshot, snaps, flags);
+
+ virResetLastError();
+
+ if (snaps)
+ *snaps = NULL;
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ if (conn->driver->domainSnapshotListAllChildren) {
+ int ret = conn->driver->domainSnapshotListAllChildren(snapshot, snaps,
+ flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotLookupByName:
+ * @domain: a domain object
+ * @name: name for the domain snapshot
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Try to lookup a domain snapshot based on its name.
+ *
+ * Returns a domain snapshot object or NULL in case of failure. If the
+ * domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
+ * error is raised.
+ */
+virDomainSnapshotPtr
+virDomainSnapshotLookupByName(virDomainPtr domain,
+ const char *name,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "name=%s, flags=%x", name, flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ virCheckNonNullArgGoto(name, error);
+
+ if (conn->driver->domainSnapshotLookupByName) {
+ virDomainSnapshotPtr dom;
+ dom = conn->driver->domainSnapshotLookupByName(domain, name, flags);
+ if (!dom)
+ goto error;
+ return dom;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainHasCurrentSnapshot:
+ * @domain: pointer to the domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Determine if the domain has a current snapshot.
+ *
+ * Returns 1 if such snapshot exists, 0 if it doesn't, -1 on error.
+ */
+int
+virDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, -1);
+ conn = domain->conn;
+
+ if (conn->driver->domainHasCurrentSnapshot) {
+ int ret = conn->driver->domainHasCurrentSnapshot(domain, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotCurrent:
+ * @domain: a domain object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Get the current snapshot for a domain, if any.
+ *
+ * virDomainSnapshotFree should be used to free the resources after the
+ * snapshot object is no longer needed.
+ *
+ * Returns a domain snapshot object or NULL in case of failure. If the
+ * current domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
+ * error is raised.
+ */
+virDomainSnapshotPtr
+virDomainSnapshotCurrent(virDomainPtr domain,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+ virResetLastError();
+
+ virCheckDomainReturn(domain, NULL);
+ conn = domain->conn;
+
+ if (conn->driver->domainSnapshotCurrent) {
+ virDomainSnapshotPtr snap;
+ snap = conn->driver->domainSnapshotCurrent(domain, flags);
+ if (!snap)
+ goto error;
+ return snap;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainSnapshotGetParent:
+ * @snapshot: a snapshot object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Get the parent snapshot for @snapshot, if any.
+ *
+ * virDomainSnapshotFree should be used to free the resources after the
+ * snapshot object is no longer needed.
+ *
+ * Returns a domain snapshot object or NULL in case of failure. If the
+ * given snapshot is a root (no parent), then the VIR_ERR_NO_DOMAIN_SNAPSHOT
+ * error is raised.
+ */
+virDomainSnapshotPtr
+virDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, NULL);
+ conn = snapshot->domain->conn;
+
+ if (conn->driver->domainSnapshotGetParent) {
+ virDomainSnapshotPtr snap;
+ snap = conn->driver->domainSnapshotGetParent(snapshot, flags);
+ if (!snap)
+ goto error;
+ return snap;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return NULL;
+}
+
+
+/**
+ * virDomainSnapshotIsCurrent:
+ * @snapshot: a snapshot object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Determine if the given snapshot is the domain's current snapshot. See
+ * also virDomainHasCurrentSnapshot().
+ *
+ * Returns 1 if current, 0 if not current, or -1 on error.
+ */
+int
+virDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ if (conn->driver->domainSnapshotIsCurrent) {
+ int ret;
+ ret = conn->driver->domainSnapshotIsCurrent(snapshot, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotHasMetadata:
+ * @snapshot: a snapshot object
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Determine if the given snapshot is associated with libvirt metadata
+ * that would prevent the deletion of the domain.
+ *
+ * Returns 1 if the snapshot has metadata, 0 if the snapshot exists without
+ * help from libvirt, or -1 on error.
+ */
+int
+virDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ if (conn->driver->domainSnapshotHasMetadata) {
+ int ret;
+ ret = conn->driver->domainSnapshotHasMetadata(snapshot, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainRevertToSnapshot:
+ * @snapshot: a domain snapshot object
+ * @flags: bitwise-OR of virDomainSnapshotRevertFlags
+ *
+ * Revert the domain to a given snapshot.
+ *
+ * Normally, the domain will revert to the same state the domain was
+ * in while the snapshot was taken (whether inactive, running, or
+ * paused), except that disk snapshots default to reverting to
+ * inactive state. Including VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING in
+ * @flags overrides the snapshot state to guarantee a running domain
+ * after the revert; or including VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED in
+ * @flags guarantees a paused domain after the revert. These two
+ * flags are mutually exclusive. While a persistent domain does not
+ * need either flag, it is not possible to revert a transient domain
+ * into an inactive state, so transient domains require the use of one
+ * of these two flags.
+ *
+ * Reverting to any snapshot discards all configuration changes made since
+ * the last snapshot. Additionally, reverting to a snapshot from a running
+ * domain is a form of data loss, since it discards whatever is in the
+ * guest's RAM at the time. Since the very nature of keeping snapshots
+ * implies the intent to roll back state, no additional confirmation is
+ * normally required for these lossy effects.
+ *
+ * However, there are two particular situations where reverting will
+ * be refused by default, and where @flags must include
+ * VIR_DOMAIN_SNAPSHOT_REVERT_FORCE to acknowledge the risks. 1) Any
+ * attempt to revert to a snapshot that lacks the metadata to perform
+ * ABI compatibility checks (generally the case for snapshots that
+ * lack a full <domain> when listed by virDomainSnapshotGetXMLDesc(),
+ * such as those created prior to libvirt 0.9.5). 2) Any attempt to
+ * revert a running domain to an active state that requires starting a
+ * new hypervisor instance rather than reusing the existing hypervisor
+ * (since this would terminate all connections to the domain, such as
+ * such as VNC or Spice graphics) - this condition arises from active
+ * snapshots that are provably ABI incomaptible, as well as from
+ * inactive snapshots with a @flags request to start the domain after
+ * the revert.
+ *
+ * Returns 0 if the creation is successful, -1 on error.
+ */
+int
+virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if ((flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
+ (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
+ virReportInvalidArg(flags,
+ _("running and paused flags in %s are mutually "
+ "exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainRevertToSnapshot) {
+ int ret = conn->driver->domainRevertToSnapshot(snapshot, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotDelete:
+ * @snapshot: a domain snapshot object
+ * @flags: bitwise-OR of supported virDomainSnapshotDeleteFlags
+ *
+ * Delete the snapshot.
+ *
+ * If @flags is 0, then just this snapshot is deleted, and changes
+ * from this snapshot are automatically merged into children
+ * snapshots. If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN,
+ * then this snapshot and any descendant snapshots are deleted. If
+ * @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, then any
+ * descendant snapshots are deleted, but this snapshot remains. These
+ * two flags are mutually exclusive.
+ *
+ * If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, then
+ * any snapshot metadata tracked by libvirt is removed while keeping
+ * the snapshot contents intact; if a hypervisor does not require any
+ * libvirt metadata to track snapshots, then this flag is silently
+ * ignored.
+ *
+ * Returns 0 if the selected snapshot(s) were successfully deleted,
+ * -1 on error.
+ */
+int
+virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+ conn = snapshot->domain->conn;
+
+ virCheckReadOnlyGoto(conn->flags, error);
+
+ if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) &&
+ (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
+ virReportInvalidArg(flags,
+ _("children and children_only flags in %s are "
+ "mutually exclusive"),
+ __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainSnapshotDelete) {
+ int ret = conn->driver->domainSnapshotDelete(snapshot, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virReportUnsupportedError();
+ error:
+ virDispatchError(conn);
+ return -1;
+}
+
+
+/**
+ * virDomainSnapshotRef:
+ * @snapshot: the snapshot to hold a reference on
+ *
+ * Increment the reference count on the snapshot. For each
+ * additional call to this method, there shall be a corresponding
+ * call to virDomainSnapshotFree to release the reference count, once
+ * the caller no longer needs the reference to this object.
+ *
+ * This method is typically useful for applications where multiple
+ * threads are using a connection, and it is required that the
+ * connection and domain remain open until all threads have finished
+ * using the snapshot. ie, each new thread using a snapshot would
+ * increment the reference count.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSnapshotRef(virDomainSnapshotPtr snapshot)
+{
+ VIR_DEBUG("snapshot=%p, refs=%d", snapshot,
+ snapshot ? snapshot->object.u.s.refs : 0);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+
+ virObjectRef(snapshot);
+ return 0;
+}
+
+
+/**
+ * virDomainSnapshotFree:
+ * @snapshot: a domain snapshot object
+ *
+ * Free the domain snapshot object. The snapshot itself is not modified.
+ * The data structure is freed and should not be used thereafter.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainSnapshotFree(virDomainSnapshotPtr snapshot)
+{
+ VIR_DEBUG("snapshot=%p", snapshot);
+
+ virResetLastError();
+
+ virCheckDomainSnapshotReturn(snapshot, -1);
+
+ virObjectUnref(snapshot);
+ return 0;
+}
diff --git a/src/libvirt.c b/src/libvirt.c
index c6af39d..f02f0d9 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -18269,1200 +18269,6 @@ virDomainManagedSaveRemove(virDomainPtr dom, unsigned int
flags)
}
-/**
- * virDomainSnapshotGetName:
- * @snapshot: a snapshot object
- *
- * Get the public name for that snapshot
- *
- * Returns a pointer to the name or NULL, the string need not be deallocated
- * as its lifetime will be the same as the snapshot object.
- */
-const char *
-virDomainSnapshotGetName(virDomainSnapshotPtr snapshot)
-{
- VIR_DEBUG("snapshot=%p", snapshot);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, NULL);
-
- return snapshot->name;
-}
-
-
-/**
- * virDomainSnapshotGetDomain:
- * @snapshot: a snapshot object
- *
- * Provides the domain pointer associated with a snapshot. The
- * reference counter on the domain is not increased by this
- * call.
- *
- * WARNING: When writing libvirt bindings in other languages, do not use this
- * function. Instead, store the domain and the snapshot object together.
- *
- * Returns the domain or NULL.
- */
-virDomainPtr
-virDomainSnapshotGetDomain(virDomainSnapshotPtr snapshot)
-{
- VIR_DEBUG("snapshot=%p", snapshot);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, NULL);
-
- return snapshot->domain;
-}
-
-
-/**
- * virDomainSnapshotGetConnect:
- * @snapshot: a snapshot object
- *
- * Provides the connection pointer associated with a snapshot. The
- * reference counter on the connection is not increased by this
- * call.
- *
- * WARNING: When writing libvirt bindings in other languages, do not use this
- * function. Instead, store the connection and the snapshot object together.
- *
- * Returns the connection or NULL.
- */
-virConnectPtr
-virDomainSnapshotGetConnect(virDomainSnapshotPtr snapshot)
-{
- VIR_DEBUG("snapshot=%p", snapshot);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, NULL);
-
- return snapshot->domain->conn;
-}
-
-
-/**
- * virDomainSnapshotCreateXML:
- * @domain: a domain object
- * @xmlDesc: string containing an XML description of the domain
- * @flags: bitwise-OR of virDomainSnapshotCreateFlags
- *
- * Creates a new snapshot of a domain based on the snapshot xml
- * contained in xmlDesc.
- *
- * If @flags is 0, the domain can be active, in which case the
- * snapshot will be a system checkpoint (both disk state and runtime
- * VM state such as RAM contents), where reverting to the snapshot is
- * the same as resuming from hibernation (TCP connections may have
- * timed out, but everything else picks up where it left off); or
- * the domain can be inactive, in which case the snapshot includes
- * just the disk state prior to booting. The newly created snapshot
- * becomes current (see virDomainSnapshotCurrent()), and is a child
- * of any previous current snapshot.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE, then this
- * is a request to reinstate snapshot metadata that was previously
- * discarded, rather than creating a new snapshot. This can be used
- * to recreate a snapshot hierarchy on a destination, then remove it
- * on the source, in order to allow migration (since migration
- * normally fails if snapshot metadata still remains on the source
- * machine). When redefining snapshot metadata, the current snapshot
- * will not be altered unless the VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
- * flag is also present. It is an error to request the
- * VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT flag without
- * VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE. On some hypervisors,
- * redefining an existing snapshot can be used to alter host-specific
- * portions of the domain XML to be used during revert (such as
- * backing filenames associated with disk devices), but must not alter
- * guest-visible layout. When redefining a snapshot name that does
- * not exist, the hypervisor may validate that reverting to the
- * snapshot appears to be possible (for example, disk images have
- * snapshot contents by the requested name). Not all hypervisors
- * support these flags.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA, then the
- * domain's disk images are modified according to @xmlDesc, but then
- * the just-created snapshot has its metadata deleted. This flag is
- * incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_HALT, then the domain
- * will be inactive after the snapshot completes, regardless of whether
- * it was active before; otherwise, a running domain will still be
- * running after the snapshot. This flag is invalid on transient domains,
- * and is incompatible with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, then the domain
- * is not paused while creating the snapshot. This increases the size
- * of the memory dump file, but reduces downtime of the guest while
- * taking the snapshot. Some hypervisors only support this flag during
- * external checkpoints.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY, then the
- * snapshot will be limited to the disks described in @xmlDesc, and no
- * VM state will be saved. For an active guest, the disk image may be
- * inconsistent (as if power had been pulled), and specifying this
- * with the VIR_DOMAIN_SNAPSHOT_CREATE_HALT flag risks data loss.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, then the
- * libvirt will attempt to use guest agent to freeze and thaw all
- * file systems in use within domain OS. However, if the guest agent
- * is not present, an error is thrown. Moreover, this flag requires
- * VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY to be passed as well.
- *
- * By default, if the snapshot involves external files, and any of the
- * destination files already exist as a non-empty regular file, the
- * snapshot is rejected to avoid losing contents of those files.
- * However, if @flags includes VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT,
- * then the destination files must be pre-created manually with
- * the correct image format and metadata including backing store path
- * (this allows a management app to pre-create files with relative backing
- * file names, rather than the default of creating with absolute backing
- * file names). Note that setting incorrect metadata in the pre-created
- * image may lead to the VM being unable to start.
- *
- * Be aware that although libvirt prefers to report errors up front with
- * no other effect, some hypervisors have certain types of failures where
- * the overall command can easily fail even though the guest configuration
- * was partially altered (for example, if a disk snapshot request for two
- * disks fails on the second disk, but the first disk alteration cannot be
- * rolled back). If this API call fails, it is therefore normally
- * necessary to follow up with virDomainGetXMLDesc() and check each disk
- * to determine if any partial changes occurred. However, if @flags
- * contains VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC, then libvirt guarantees
- * that this command will not alter any disks unless the entire set of
- * changes can be done atomically, making failure recovery simpler (note
- * that it is still possible to fail after disks have changed, but only
- * in the much rarer cases of running out of memory or disk space).
- *
- * Some hypervisors may prevent this operation if there is a current
- * block copy operation; in that case, use virDomainBlockJobAbort()
- * to stop the block copy first.
- *
- * virDomainSnapshotFree should be used to free the resources after the
- * snapshot object is no longer needed.
- *
- * Returns an (opaque) virDomainSnapshotPtr on success, NULL on failure.
- */
-virDomainSnapshotPtr
-virDomainSnapshotCreateXML(virDomainPtr domain,
- const char *xmlDesc,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "xmlDesc=%s, flags=%x", xmlDesc, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(xmlDesc, error);
- virCheckReadOnlyGoto(conn->flags, error);
-
- if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) &&
- !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
- virReportInvalidArg(flags,
- _("use of 'current' flag in %s requires "
- "'redefine' flag"),
- __FUNCTION__);
- goto error;
- }
- if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
- (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
- virReportInvalidArg(flags,
- _("'redefine' and 'no metadata' flags in
%s are "
- "mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
- if ((flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) &&
- (flags & VIR_DOMAIN_SNAPSHOT_CREATE_HALT)) {
- virReportInvalidArg(flags,
- _("'redefine' and 'halt' flags in %s are
mutually "
- "exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainSnapshotCreateXML) {
- virDomainSnapshotPtr ret;
- ret = conn->driver->domainSnapshotCreateXML(domain, xmlDesc, flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainSnapshotGetXMLDesc:
- * @snapshot: a domain snapshot object
- * @flags: bitwise-OR of subset of virDomainXMLFlags
- *
- * Provide an XML description of the domain snapshot.
- *
- * No security-sensitive data will be included unless @flags contains
- * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
- * connections. For this API, @flags should not contain either
- * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
- *
- * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
- * the caller must free() the returned value.
- */
-char *
-virDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, NULL);
- conn = snapshot->domain->conn;
-
- if ((conn->flags & VIR_CONNECT_RO) && (flags &
VIR_DOMAIN_XML_SECURE)) {
- virReportError(VIR_ERR_OPERATION_DENIED, "%s",
- _("virDomainSnapshotGetXMLDesc with secure flag"));
- goto error;
- }
-
- if (conn->driver->domainSnapshotGetXMLDesc) {
- char *ret;
- ret = conn->driver->domainSnapshotGetXMLDesc(snapshot, flags);
- if (!ret)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainSnapshotNum:
- * @domain: a domain object
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Provides the number of domain snapshots for this domain.
- *
- * By default, this command covers all snapshots; it is also possible to
- * limit things to just snapshots with no parents, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Returns the number of domain snapshots found or -1 in case of error.
- */
-int
-virDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
-
- conn = domain->conn;
- if (conn->driver->domainSnapshotNum) {
- int ret = conn->driver->domainSnapshotNum(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotListNames:
- * @domain: a domain object
- * @names: array to collect the list of names of snapshots
- * @nameslen: size of @names
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Collect the list of domain snapshots for the given domain, and store
- * their names in @names. The value to use for @nameslen can be determined
- * by virDomainSnapshotNum() with the same @flags.
- *
- * By default, this command covers all snapshots; it is also possible to
- * limit things to just snapshots with no parents, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Note that this command is inherently racy: another connection can
- * define a new snapshot between a call to virDomainSnapshotNum() and
- * this call. You are only guaranteed that all currently defined
- * snapshots were listed if the return is less than @nameslen. Likewise,
- * you should be prepared for virDomainSnapshotLookupByName() to fail when
- * converting a name from this call into a snapshot object, if another
- * connection deletes the snapshot in the meantime. For more control over
- * the results, see virDomainListAllSnapshots().
- *
- * Returns the number of domain snapshots found or -1 in case of error.
- * The caller is responsible to call free() for each member of the array.
- */
-int
-virDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "names=%p, nameslen=%d, flags=%x",
- names, nameslen, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(names, error);
- virCheckNonNegativeArgGoto(nameslen, error);
-
- if (conn->driver->domainSnapshotListNames) {
- int ret = conn->driver->domainSnapshotListNames(domain, names,
- nameslen, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainListAllSnapshots:
- * @domain: a domain object
- * @snaps: pointer to variable to store the array containing snapshot objects,
- * or NULL if the list is not required (just returns number of
- * snapshots)
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Collect the list of domain snapshots for the given domain, and allocate
- * an array to store those objects. This API solves the race inherent in
- * virDomainSnapshotListNames().
- *
- * By default, this command covers all snapshots; it is also possible to
- * limit things to just snapshots with no parents, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_ROOTS. Additional filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Returns the number of domain snapshots found or -1 and sets @snaps to
- * NULL in case of error. On success, the array stored into @snaps is
- * guaranteed to have an extra allocated element set to NULL but not included
- * in the return count, to make iteration easier. The caller is responsible
- * for calling virDomainSnapshotFree() on each array element, then calling
- * free() on @snaps.
- */
-int
-virDomainListAllSnapshots(virDomainPtr domain, virDomainSnapshotPtr **snaps,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "snaps=%p, flags=%x", snaps, flags);
-
- virResetLastError();
-
- if (snaps)
- *snaps = NULL;
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- if (conn->driver->domainListAllSnapshots) {
- int ret = conn->driver->domainListAllSnapshots(domain, snaps, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotNumChildren:
- * @snapshot: a domain snapshot object
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Provides the number of child snapshots for this domain snapshot.
- *
- * By default, this command covers only direct children; it is also possible
- * to expand things to cover all descendants, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Returns the number of domain snapshots found or -1 in case of error.
- */
-int
-virDomainSnapshotNumChildren(virDomainSnapshotPtr snapshot, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- if (conn->driver->domainSnapshotNumChildren) {
- int ret = conn->driver->domainSnapshotNumChildren(snapshot, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotListChildrenNames:
- * @snapshot: a domain snapshot object
- * @names: array to collect the list of names of snapshots
- * @nameslen: size of @names
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Collect the list of domain snapshots that are children of the given
- * snapshot, and store their names in @names. The value to use for
- * @nameslen can be determined by virDomainSnapshotNumChildren() with
- * the same @flags.
- *
- * By default, this command covers only direct children; it is also possible
- * to expand things to cover all descendants, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Returns the number of domain snapshots found or -1 in case of error.
- * Note that this command is inherently racy: another connection can
- * define a new snapshot between a call to virDomainSnapshotNumChildren()
- * and this call. You are only guaranteed that all currently defined
- * snapshots were listed if the return is less than @nameslen. Likewise,
- * you should be prepared for virDomainSnapshotLookupByName() to fail when
- * converting a name from this call into a snapshot object, if another
- * connection deletes the snapshot in the meantime. For more control over
- * the results, see virDomainSnapshotListAllChildren().
- *
- * Returns the number of domain snapshots found or -1 in case of error.
- * The caller is responsible to call free() for each member of the array.
- */
-int
-virDomainSnapshotListChildrenNames(virDomainSnapshotPtr snapshot,
- char **names, int nameslen,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, names=%p, nameslen=%d, flags=%x",
- snapshot, names, nameslen, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- virCheckNonNullArgGoto(names, error);
- virCheckNonNegativeArgGoto(nameslen, error);
-
- if (conn->driver->domainSnapshotListChildrenNames) {
- int ret = conn->driver->domainSnapshotListChildrenNames(snapshot,
- names,
- nameslen,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotListAllChildren:
- * @snapshot: a domain snapshot object
- * @snaps: pointer to variable to store the array containing snapshot objects,
- * or NULL if the list is not required (just returns number of
- * snapshots)
- * @flags: bitwise-OR of supported virDomainSnapshotListFlags
- *
- * Collect the list of domain snapshots that are children of the given
- * snapshot, and allocate an array to store those objects. This API solves
- * the race inherent in virDomainSnapshotListChildrenNames().
- *
- * By default, this command covers only direct children; it is also possible
- * to expand things to cover all descendants, when @flags includes
- * VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS. Also, some filters are provided in
- * groups, where each group contains bits that describe mutually exclusive
- * attributes of a snapshot, and where all bits within a group describe
- * all possible snapshots. Some hypervisors might reject explicit bits
- * from a group where the hypervisor cannot make a distinction. For a
- * group supported by a given hypervisor, the behavior when no bits of a
- * group are set is identical to the behavior when all bits in that group
- * are set. When setting bits from more than one group, it is possible to
- * select an impossible combination, in that case a hypervisor may return
- * either 0 or an error.
- *
- * The first group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_LEAVES and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES, to filter based on snapshots that
- * have no further children (a leaf snapshot).
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_METADATA and
- * VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA, for filtering snapshots based on
- * whether they have metadata that would prevent the removal of the last
- * reference to a domain.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE,
- * VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE, and VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY,
- * for filtering snapshots based on what domain state is tracked by the
- * snapshot.
- *
- * The next group of @flags is VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL and
- * VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL, for filtering snapshots based on
- * whether the snapshot is stored inside the disk images or as
- * additional files.
- *
- * Returns the number of domain snapshots found or -1 and sets @snaps to
- * NULL in case of error. On success, the array stored into @snaps is
- * guaranteed to have an extra allocated element set to NULL but not included
- * in the return count, to make iteration easier. The caller is responsible
- * for calling virDomainSnapshotFree() on each array element, then calling
- * free() on @snaps.
- */
-int
-virDomainSnapshotListAllChildren(virDomainSnapshotPtr snapshot,
- virDomainSnapshotPtr **snaps,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, snaps=%p, flags=%x", snapshot, snaps, flags);
-
- virResetLastError();
-
- if (snaps)
- *snaps = NULL;
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- if (conn->driver->domainSnapshotListAllChildren) {
- int ret = conn->driver->domainSnapshotListAllChildren(snapshot, snaps,
- flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotLookupByName:
- * @domain: a domain object
- * @name: name for the domain snapshot
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Try to lookup a domain snapshot based on its name.
- *
- * Returns a domain snapshot object or NULL in case of failure. If the
- * domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
- * error is raised.
- */
-virDomainSnapshotPtr
-virDomainSnapshotLookupByName(virDomainPtr domain,
- const char *name,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "name=%s, flags=%x", name, flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- virCheckNonNullArgGoto(name, error);
-
- if (conn->driver->domainSnapshotLookupByName) {
- virDomainSnapshotPtr dom;
- dom = conn->driver->domainSnapshotLookupByName(domain, name, flags);
- if (!dom)
- goto error;
- return dom;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainHasCurrentSnapshot:
- * @domain: pointer to the domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Determine if the domain has a current snapshot.
- *
- * Returns 1 if such snapshot exists, 0 if it doesn't, -1 on error.
- */
-int
-virDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, -1);
- conn = domain->conn;
-
- if (conn->driver->domainHasCurrentSnapshot) {
- int ret = conn->driver->domainHasCurrentSnapshot(domain, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotCurrent:
- * @domain: a domain object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get the current snapshot for a domain, if any.
- *
- * virDomainSnapshotFree should be used to free the resources after the
- * snapshot object is no longer needed.
- *
- * Returns a domain snapshot object or NULL in case of failure. If the
- * current domain snapshot cannot be found, then the VIR_ERR_NO_DOMAIN_SNAPSHOT
- * error is raised.
- */
-virDomainSnapshotPtr
-virDomainSnapshotCurrent(virDomainPtr domain,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
-
- virResetLastError();
-
- virCheckDomainReturn(domain, NULL);
- conn = domain->conn;
-
- if (conn->driver->domainSnapshotCurrent) {
- virDomainSnapshotPtr snap;
- snap = conn->driver->domainSnapshotCurrent(domain, flags);
- if (!snap)
- goto error;
- return snap;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainSnapshotGetParent:
- * @snapshot: a snapshot object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Get the parent snapshot for @snapshot, if any.
- *
- * virDomainSnapshotFree should be used to free the resources after the
- * snapshot object is no longer needed.
- *
- * Returns a domain snapshot object or NULL in case of failure. If the
- * given snapshot is a root (no parent), then the VIR_ERR_NO_DOMAIN_SNAPSHOT
- * error is raised.
- */
-virDomainSnapshotPtr
-virDomainSnapshotGetParent(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, NULL);
- conn = snapshot->domain->conn;
-
- if (conn->driver->domainSnapshotGetParent) {
- virDomainSnapshotPtr snap;
- snap = conn->driver->domainSnapshotGetParent(snapshot, flags);
- if (!snap)
- goto error;
- return snap;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return NULL;
-}
-
-
-/**
- * virDomainSnapshotIsCurrent:
- * @snapshot: a snapshot object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Determine if the given snapshot is the domain's current snapshot. See
- * also virDomainHasCurrentSnapshot().
- *
- * Returns 1 if current, 0 if not current, or -1 on error.
- */
-int
-virDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- if (conn->driver->domainSnapshotIsCurrent) {
- int ret;
- ret = conn->driver->domainSnapshotIsCurrent(snapshot, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotHasMetadata:
- * @snapshot: a snapshot object
- * @flags: extra flags; not used yet, so callers should always pass 0
- *
- * Determine if the given snapshot is associated with libvirt metadata
- * that would prevent the deletion of the domain.
- *
- * Returns 1 if the snapshot has metadata, 0 if the snapshot exists without
- * help from libvirt, or -1 on error.
- */
-int
-virDomainSnapshotHasMetadata(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- if (conn->driver->domainSnapshotHasMetadata) {
- int ret;
- ret = conn->driver->domainSnapshotHasMetadata(snapshot, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainRevertToSnapshot:
- * @snapshot: a domain snapshot object
- * @flags: bitwise-OR of virDomainSnapshotRevertFlags
- *
- * Revert the domain to a given snapshot.
- *
- * Normally, the domain will revert to the same state the domain was
- * in while the snapshot was taken (whether inactive, running, or
- * paused), except that disk snapshots default to reverting to
- * inactive state. Including VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING in
- * @flags overrides the snapshot state to guarantee a running domain
- * after the revert; or including VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED in
- * @flags guarantees a paused domain after the revert. These two
- * flags are mutually exclusive. While a persistent domain does not
- * need either flag, it is not possible to revert a transient domain
- * into an inactive state, so transient domains require the use of one
- * of these two flags.
- *
- * Reverting to any snapshot discards all configuration changes made since
- * the last snapshot. Additionally, reverting to a snapshot from a running
- * domain is a form of data loss, since it discards whatever is in the
- * guest's RAM at the time. Since the very nature of keeping snapshots
- * implies the intent to roll back state, no additional confirmation is
- * normally required for these lossy effects.
- *
- * However, there are two particular situations where reverting will
- * be refused by default, and where @flags must include
- * VIR_DOMAIN_SNAPSHOT_REVERT_FORCE to acknowledge the risks. 1) Any
- * attempt to revert to a snapshot that lacks the metadata to perform
- * ABI compatibility checks (generally the case for snapshots that
- * lack a full <domain> when listed by virDomainSnapshotGetXMLDesc(),
- * such as those created prior to libvirt 0.9.5). 2) Any attempt to
- * revert a running domain to an active state that requires starting a
- * new hypervisor instance rather than reusing the existing hypervisor
- * (since this would terminate all connections to the domain, such as
- * such as VNC or Spice graphics) - this condition arises from active
- * snapshots that are provably ABI incomaptible, as well as from
- * inactive snapshots with a @flags request to start the domain after
- * the revert.
- *
- * Returns 0 if the creation is successful, -1 on error.
- */
-int
-virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if ((flags & VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) &&
- (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
- virReportInvalidArg(flags,
- _("running and paused flags in %s are mutually "
- "exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainRevertToSnapshot) {
- int ret = conn->driver->domainRevertToSnapshot(snapshot, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotDelete:
- * @snapshot: a domain snapshot object
- * @flags: bitwise-OR of supported virDomainSnapshotDeleteFlags
- *
- * Delete the snapshot.
- *
- * If @flags is 0, then just this snapshot is deleted, and changes
- * from this snapshot are automatically merged into children
- * snapshots. If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN,
- * then this snapshot and any descendant snapshots are deleted. If
- * @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, then any
- * descendant snapshots are deleted, but this snapshot remains. These
- * two flags are mutually exclusive.
- *
- * If @flags includes VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, then
- * any snapshot metadata tracked by libvirt is removed while keeping
- * the snapshot contents intact; if a hypervisor does not require any
- * libvirt metadata to track snapshots, then this flag is silently
- * ignored.
- *
- * Returns 0 if the selected snapshot(s) were successfully deleted,
- * -1 on error.
- */
-int
-virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
- unsigned int flags)
-{
- virConnectPtr conn;
-
- VIR_DEBUG("snapshot=%p, flags=%x", snapshot, flags);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
- conn = snapshot->domain->conn;
-
- virCheckReadOnlyGoto(conn->flags, error);
-
- if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) &&
- (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) {
- virReportInvalidArg(flags,
- _("children and children_only flags in %s are "
- "mutually exclusive"),
- __FUNCTION__);
- goto error;
- }
-
- if (conn->driver->domainSnapshotDelete) {
- int ret = conn->driver->domainSnapshotDelete(snapshot, flags);
- if (ret < 0)
- goto error;
- return ret;
- }
-
- virReportUnsupportedError();
- error:
- virDispatchError(conn);
- return -1;
-}
-
-
-/**
- * virDomainSnapshotRef:
- * @snapshot: the snapshot to hold a reference on
- *
- * Increment the reference count on the snapshot. For each
- * additional call to this method, there shall be a corresponding
- * call to virDomainSnapshotFree to release the reference count, once
- * the caller no longer needs the reference to this object.
- *
- * This method is typically useful for applications where multiple
- * threads are using a connection, and it is required that the
- * connection and domain remain open until all threads have finished
- * using the snapshot. ie, each new thread using a snapshot would
- * increment the reference count.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSnapshotRef(virDomainSnapshotPtr snapshot)
-{
- VIR_DEBUG("snapshot=%p, refs=%d", snapshot,
- snapshot ? snapshot->object.u.s.refs : 0);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
-
- virObjectRef(snapshot);
- return 0;
-}
-
-
-/**
- * virDomainSnapshotFree:
- * @snapshot: a domain snapshot object
- *
- * Free the domain snapshot object. The snapshot itself is not modified.
- * The data structure is freed and should not be used thereafter.
- *
- * Returns 0 in case of success and -1 in case of failure.
- */
-int
-virDomainSnapshotFree(virDomainSnapshotPtr snapshot)
-{
- VIR_DEBUG("snapshot=%p", snapshot);
-
- virResetLastError();
-
- virCheckDomainSnapshotReturn(snapshot, -1);
-
- virObjectUnref(snapshot);
- return 0;
-}
-
/**
* virDomainOpenConsole:
--
2.1.0