Reverting to a state prior to an external snapshot risks corrupting any other branches in the snapshot hierarchy that were using the snapshot as a read-only backing file. So disk snapshot code will default to preventing reverting to a snapshot that has any children, meaning that deleting just the children of a snapshot becomes a useful operation in preparing that snapshot for being a future reversion target. The code for the new flag is simple - it's one less deletion. * include/libvirt/libvirt.h.in (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY): New flag. * src/libvirt.c (virDomainSnapshotDelete): Document it, and enforce mutual exclusion. * src/qemu/qemu_driver.c (qemuDomainSnapshotDelete): Implement it. --- include/libvirt/libvirt.h.in | 1 + src/libvirt.c | 32 +++++++++++++++++++++++--------- src/qemu/qemu_driver.c | 11 ++++++++--- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 36f1b34..49fe6b3 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2607,6 +2607,7 @@ int virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, 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 */ } virDomainSnapshotDeleteFlags; int virDomainSnapshotDelete(virDomainSnapshotPtr snapshot, diff --git a/src/libvirt.c b/src/libvirt.c index fac2047..2c84e7e 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -15857,16 +15857,22 @@ error: * * 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 children snapshots are deleted. 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. + * 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. * - * Returns 0 if the snapshot was successfully deleted, -1 on error. + * 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, @@ -15891,6 +15897,14 @@ virDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto error; } + if ((flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) && + (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) { + virLibDomainError(VIR_ERR_INVALID_ARG, + _("children and children_only flags are " + "mutually exclusive")); + goto error; + } + if (conn->driver->domainSnapshotDelete) { int ret = conn->driver->domainSnapshotDelete(snapshot, flags); if (ret < 0) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 165396d..822d90c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9247,7 +9247,8 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY); virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN | - VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY, -1); + VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY | + VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY, -1); qemuDriverLock(driver); virUUIDFormat(snapshot->domain->uuid, uuidstr); @@ -9269,7 +9270,8 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; - if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) { + if (flags & (VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN | + VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY)) { rem.driver = driver; rem.vm = vm; rem.metadata_only = metadata_only; @@ -9292,7 +9294,10 @@ static int qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot, goto endjob; } - ret = qemuDomainSnapshotDiscard(driver, vm, snap, metadata_only); + if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) + ret = 0; + else + ret = qemuDomainSnapshotDiscard(driver, vm, snap, metadata_only); endjob: if (qemuDomainObjEndJob(driver, vm) == 0) -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list