This is to delete a snapshot object atomically, the API accepts
argments: domain object, snapshot name and flags. When name is
NULL, the current snapshot object will be deleted
include/libvirt/libvirt.h.in: Declare virDomainSnapshotDeleteByName
src/driver.h: (virDrvDomainSnapshotDeleteByName)
src/libvirt.c: Implement the public API
src/libvirt_public.syms: Export the symbol to public
---
include/libvirt/libvirt.h.in | 4 +++
src/driver.h | 6 ++++
src/libvirt.c | 71 ++++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++++
4 files changed, 86 insertions(+)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index b791125..e7e75c0 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4433,6 +4433,10 @@ typedef enum {
int virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
unsigned int flags);
+int virDomainSnapshotDeleteByName(virDomainPtr domain,
+ const char *name,
+ unsigned int flags);
+
int virDomainSnapshotRef(virDomainSnapshotPtr snapshot);
int virDomainSnapshotFree(virDomainSnapshotPtr snapshot);
diff --git a/src/driver.h b/src/driver.h
index 31851cb..8651603 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -801,6 +801,11 @@ typedef int
unsigned int flags);
typedef int
+(*virDrvDomainSnapshotDeleteByName)(virDomainPtr domain,
+ const char *cmd,
+ unsigned int flags);
+
+typedef int
(*virDrvDomainQemuMonitorCommand)(virDomainPtr domain,
const char *cmd,
char **result,
@@ -1272,6 +1277,7 @@ struct _virDriver {
virDrvDomainSnapshotHasMetadata domainSnapshotHasMetadata;
virDrvDomainRevertToSnapshot domainRevertToSnapshot;
virDrvDomainSnapshotDelete domainSnapshotDelete;
+ virDrvDomainSnapshotDeleteByName domainSnapshotDeleteByName;
virDrvDomainQemuMonitorCommand domainQemuMonitorCommand;
virDrvDomainQemuAttach domainQemuAttach;
virDrvDomainQemuAgentCommand domainQemuAgentCommand;
diff --git a/src/libvirt.c b/src/libvirt.c
index bc1694a..aa04959 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -20158,6 +20158,10 @@ error:
* libvirt metadata to track snapshots, then this flag is silently
* ignored.
*
+ * Note that this command is inherently racy: another connection can
+ * delete the snapshot object between a call to virDomainSnapshotLookupByName()
+ * and this call.
+ *
* Returns 0 if the selected snapshot(s) were successfully deleted,
* -1 on error.
*/
@@ -20207,6 +20211,73 @@ error:
}
/**
+ * virDomainSnapshotDeleteByName:
+ * @domain: pointer to the domain object
+ * @name : snapshot name or NULL
+ * @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
+virDomainSnapshotDeleteByName(virDomainPtr domain,
+ const char *name,
+ unsigned int flags)
+{
+ VIR_DOMAIN_DEBUG(domain, "name=%s, flags=%x", name, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_DOMAIN(domain)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (domain->conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto 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 (domain->conn->driver->domainSnapshotDelete) {
+ int ret = domain->conn->driver->domainSnapshotDeleteByName(domain, name,
flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+error:
+ virDispatchError(domain->conn);
+ return -1;
+}
+
+/**
* virDomainSnapshotRef:
* @snapshot: the snapshot to hold a reference on
*
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 7c6edf6..24826b8 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -627,4 +627,9 @@ LIBVIRT_1.1.0 {
virDomainMigrateToURI3;
} LIBVIRT_1.0.6;
+LIBVIRT_1.1.1 {
+ global:
+ virDomainSnapshotDeleteByName;
+}LIBVIRT_1.1.0;
+
# .... define new API here using predicted next version number ....
--
1.8.1.4