This is to delete a snapshot object atomically, the API accepts argments: domain object, snapshot name and flags. Add a new flag VIR_DOMAIN_SNAPSHOT_DELETE_CURRENT, others are same. include/libvirt/libvirt.h.in: Declare virDomainSnapshotDeleteByName Add VIR_DOMAIN_SNAPSHOT_DELETE_CURRENT 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 | 5 +++ src/driver.h | 6 ++++ src/libvirt.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 5 +++ 4 files changed, 89 insertions(+) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 574b970..fa90197 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4339,11 +4339,16 @@ typedef enum { VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN = (1 << 0), /* Also delete children */ VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY = (1 << 1), /* Delete just metadata */ VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY = (1 << 2), /* Delete just children */ + VIR_DOMAIN_SNAPSHOT_DELETE_CURRENT = (1 << 3), /* Delete current snapshot */ } virDomainSnapshotDeleteFlags; 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 ec5fc53..24dd262 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, @@ -1211,6 +1216,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 620dbdd..cf5de87 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -19346,6 +19346,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. */ @@ -19395,6 +19399,75 @@ 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_CURRENT, current snapshot is deleted, + * in this case the @name will be ingored. + * + * 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 4ee2d27..6b4cac2 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -621,4 +621,9 @@ LIBVIRT_1.0.6 { virGetLastErrorMessage; } LIBVIRT_1.0.5; +LIBVIRT_1.0.7 { + global: + virDomainSnapshotDeleteByName; +}LIBVIRT_1.0.6; + # .... define new API here using predicted next version number .... -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list