[libvirt RFC 12/24] qemu_snapshot: rework snapshot children deletion
Peter Krempa
pkrempa at redhat.com
Thu Sep 1 14:09:48 UTC 2022
On Tue, Aug 23, 2022 at 18:32:15 +0200, Pavel Hrdina wrote:
> This simplifies the code a bit by reusing existing parts that deletes
> a single snapshot.
You should mention that the tradeoff is that some steps will get
executed multiple times.
>
> Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
> ---
> src/qemu/qemu_snapshot.c | 69 ++++++++++++++++++++++------------------
> 1 file changed, 38 insertions(+), 31 deletions(-)
>
> diff --git a/src/qemu/qemu_snapshot.c b/src/qemu/qemu_snapshot.c
> index d40d75e75d..db04244018 100644
> --- a/src/qemu/qemu_snapshot.c
> +++ b/src/qemu/qemu_snapshot.c
> @@ -2310,6 +2310,33 @@ qemuSnapshotDeleteSingle(virDomainObj *vm,
> }
>
>
> +struct qemuSnapshotDeleteAllData {
> + virDomainObj *vm;
> + virQEMUDriver *driver;
> + bool metadata_only;
> + int error;
> +};
> +
> +
> +static int
> +qemuSnapshotDeleteAll(void *payload,
> + const char *name G_GNUC_UNUSED,
> + void *opaque)
> +{
> + int error;
> + virDomainMomentObj *snap = payload;
> + struct qemuSnapshotDeleteAllData *data = opaque;
> +
> + error = qemuSnapshotDeleteSingle(data->vm, snap, data->driver,
> + data->metadata_only);
> +
> + if (error != 0 && data->error != 0)
So 'data->error' is initialized to '0' in the caller. By the logic above
you'll never write to it if 'error' will actually carry a non-zero
value.
Since it's used as a glorified boolean (having only '0' or '-1' stored
in it) I think you can drop the '&& data->error != 0) altogether and
always update it when an error occured.
> + data->error = error;
> +
> + return 0;
> +}
> +
> +
> static int
> qemuSnapshotDeleteChildren(virDomainObj *vm,
> virDomainMomentObj *snap,
> @@ -2317,42 +2344,22 @@ qemuSnapshotDeleteChildren(virDomainObj *vm,
> bool metadata_only,
> unsigned int flags)
> {
> - virQEMUMomentRemove rem;
> - g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
> + struct qemuSnapshotDeleteAllData data = { 0 };
[1]. Also I'd go with c99 style init ...
>
> - rem.driver = driver;
> - rem.vm = vm;
> - rem.metadata_only = metadata_only;
> - rem.err = 0;
> - rem.current = virDomainSnapshotGetCurrent(vm->snapshots);
> - rem.found = false;
> - rem.momentDiscard = qemuDomainSnapshotDiscard;
> - virDomainMomentForEachDescendant(snap, qemuDomainMomentDiscardAll,
> - &rem);
> - if (rem.err < 0)
> + data.vm = vm;
> + data.driver = driver;
> + data.metadata_only = metadata_only;
... to make this more obvious.
> +
> + virDomainMomentForEachDescendant(snap, qemuSnapshotDeleteAll, &data);
> +
> + if (data.error < 0)
> return -1;
> - if (rem.found) {
> - qemuSnapshotSetCurrent(vm, snap);
>
> - if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
> - if (qemuDomainSnapshotWriteMetadata(vm, snap,
> - driver->xmlopt,
> - cfg->snapshotDir) < 0) {
> - virReportError(VIR_ERR_INTERNAL_ERROR,
> - _("failed to set snapshot '%s' as current"),
> - snap->def->name);
> - virDomainSnapshotSetCurrent(vm->snapshots, NULL);
> - return -1;
> - }
> - }
> + if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) {
> + return qemuSnapshotDeleteSingle(vm, snap, driver, metadata_only);
Preferrably check that qemuSnapshotDeleteSingle returns -1 and return
failure here instead ...
> }
>
> - if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
> - virDomainMomentDropChildren(snap);
> - return 0;
> - }
> -
> - return qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
> + return 0;
So that we have the usual control flow.
> }
>
>
> --
> 2.37.2
>
More information about the libvir-list
mailing list