snapshot: Refactor qemu to utilize virDomainMoment more

Use the common base class virDomainMoment for iterator callbacks
related to snapshots from the qemu code, so that when checkpoint
operations are introduced, they can share the same callbacks.

Simplify the code for qemuDomainSnapshotCurrent by better utilizing
virDomainMoment helpers.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Eric Blake 2019-03-27 02:12:37 -05:00
parent 6b90a84738
commit a487890d37
3 changed files with 57 additions and 49 deletions

View File

@ -1,7 +1,7 @@
/* /*
* qemu_domain.c: QEMU domain private state * qemu_domain.c: QEMU domain private state
* *
* Copyright (C) 2006-2016 Red Hat, Inc. * Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange * Copyright (C) 2006 Daniel P. Berrange
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -8650,18 +8650,18 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
} }
/* Hash iterator callback to discard multiple snapshots. */ /* Hash iterator callback to discard multiple snapshots. */
int qemuDomainSnapshotDiscardAll(void *payload, int qemuDomainMomentDiscardAll(void *payload,
const void *name ATTRIBUTE_UNUSED, const void *name ATTRIBUTE_UNUSED,
void *data) void *data)
{ {
virDomainMomentObjPtr snap = payload; virDomainMomentObjPtr moment = payload;
virQEMUSnapRemovePtr curr = data; virQEMUMomentRemovePtr curr = data;
int err; int err;
if (virDomainSnapshotGetCurrent(curr->vm->snapshots) == snap) if (!curr->found && curr->current == moment)
curr->current = true; curr->found = true;
err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false, err = curr->momentDiscard(curr->driver, curr->vm, moment, false,
curr->metadata_only); curr->metadata_only);
if (err && !curr->err) if (err && !curr->err)
curr->err = err; curr->err = err;
return 0; return 0;
@ -8671,14 +8671,13 @@ int
qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
virDomainObjPtr vm) virDomainObjPtr vm)
{ {
virQEMUSnapRemove rem; virQEMUMomentRemove rem = {
.driver = driver,
.vm = vm,
.metadata_only = true
};
rem.driver = driver; virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem);
rem.vm = vm;
rem.metadata_only = true;
rem.err = 0;
virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll,
&rem);
virDomainSnapshotObjListRemoveAll(vm->snapshots); virDomainSnapshotObjListRemoveAll(vm->snapshots);
return rem.err; return rem.err;

View File

@ -1,7 +1,7 @@
/* /*
* qemu_domain.h: QEMU domain private state * qemu_domain.h: QEMU domain private state
* *
* Copyright (C) 2006-2016 Red Hat, Inc. * Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange * Copyright (C) 2006 Daniel P. Berrange
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -38,6 +38,7 @@
# include "virchrdev.h" # include "virchrdev.h"
# include "virobject.h" # include "virobject.h"
# include "logging/log_manager.h" # include "logging/log_manager.h"
# include "virdomainmomentobjlist.h"
# define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \ # define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
(VIR_DOMAIN_XML_SECURE) (VIR_DOMAIN_XML_SECURE)
@ -698,19 +699,22 @@ int qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
bool update_current, bool update_current,
bool metadata_only); bool metadata_only);
typedef struct _virQEMUSnapRemove virQEMUSnapRemove; typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
typedef virQEMUSnapRemove *virQEMUSnapRemovePtr; typedef virQEMUMomentRemove *virQEMUMomentRemovePtr;
struct _virQEMUSnapRemove { struct _virQEMUMomentRemove {
virQEMUDriverPtr driver; virQEMUDriverPtr driver;
virDomainObjPtr vm; virDomainObjPtr vm;
int err; int err;
bool metadata_only; bool metadata_only;
bool current; virDomainMomentObjPtr current;
bool found;
int (*momentDiscard)(virQEMUDriverPtr, virDomainObjPtr,
virDomainMomentObjPtr, bool, bool);
}; };
int qemuDomainSnapshotDiscardAll(void *payload, int qemuDomainMomentDiscardAll(void *payload,
const void *name, const void *name,
void *data); void *data);
int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver, int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
virDomainObjPtr vm); virDomainObjPtr vm);

View File

@ -16126,6 +16126,7 @@ qemuDomainSnapshotCurrent(virDomainPtr domain,
{ {
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainSnapshotPtr snapshot = NULL; virDomainSnapshotPtr snapshot = NULL;
const char *name;
virCheckFlags(0, NULL); virCheckFlags(0, NULL);
@ -16135,13 +16136,14 @@ qemuDomainSnapshotCurrent(virDomainPtr domain,
if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0) if (virDomainSnapshotCurrentEnsureACL(domain->conn, vm->def) < 0)
goto cleanup; goto cleanup;
if (!virDomainSnapshotGetCurrent(vm->snapshots)) { name = virDomainSnapshotGetCurrentName(vm->snapshots);
if (!name) {
virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s", virReportError(VIR_ERR_NO_DOMAIN_SNAPSHOT, "%s",
_("the domain does not have a current snapshot")); _("the domain does not have a current snapshot"));
goto cleanup; goto cleanup;
} }
snapshot = virGetDomainSnapshot(domain, virDomainSnapshotGetCurrentName(vm->snapshots)); snapshot = virGetDomainSnapshot(domain, name);
cleanup: cleanup:
virDomainObjEndAPI(&vm); virDomainObjEndAPI(&vm);
@ -16673,40 +16675,41 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
} }
typedef struct _virQEMUSnapReparent virQEMUSnapReparent; typedef struct _virQEMUMomentReparent virQEMUMomentReparent;
typedef virQEMUSnapReparent *virQEMUSnapReparentPtr; typedef virQEMUMomentReparent *virQEMUMomentReparentPtr;
struct _virQEMUSnapReparent { struct _virQEMUMomentReparent {
virQEMUDriverConfigPtr cfg; const char *dir;
virDomainMomentObjPtr parent; virDomainMomentObjPtr parent;
virDomainObjPtr vm; virDomainObjPtr vm;
virCapsPtr caps; virCapsPtr caps;
virDomainXMLOptionPtr xmlopt; virDomainXMLOptionPtr xmlopt;
int err; int err;
int (*writeMetadata)(virDomainObjPtr, virDomainMomentObjPtr,
virCapsPtr, virDomainXMLOptionPtr, const char *);
}; };
static int static int
qemuDomainSnapshotReparentChildren(void *payload, qemuDomainMomentReparentChildren(void *payload,
const void *name ATTRIBUTE_UNUSED, const void *name ATTRIBUTE_UNUSED,
void *data) void *data)
{ {
virDomainMomentObjPtr snap = payload; virDomainMomentObjPtr moment = payload;
virQEMUSnapReparentPtr rep = data; virQEMUMomentReparentPtr rep = data;
if (rep->err < 0) if (rep->err < 0)
return 0; return 0;
VIR_FREE(snap->def->parent); VIR_FREE(moment->def->parent);
if (rep->parent->def && if (rep->parent->def &&
VIR_STRDUP(snap->def->parent, rep->parent->def->name) < 0) { VIR_STRDUP(moment->def->parent, rep->parent->def->name) < 0) {
rep->err = -1; rep->err = -1;
return 0; return 0;
} }
rep->err = qemuDomainSnapshotWriteMetadata(rep->vm, snap, rep->err = rep->writeMetadata(rep->vm, moment, rep->caps, rep->xmlopt,
rep->caps, rep->xmlopt, rep->dir);
rep->cfg->snapshotDir);
return 0; return 0;
} }
@ -16719,8 +16722,8 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
virDomainObjPtr vm = NULL; virDomainObjPtr vm = NULL;
int ret = -1; int ret = -1;
virDomainMomentObjPtr snap = NULL; virDomainMomentObjPtr snap = NULL;
virQEMUSnapRemove rem; virQEMUMomentRemove rem;
virQEMUSnapReparent rep; virQEMUMomentReparent rep;
bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY); bool metadata_only = !!(flags & VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY);
int external = 0; int external = 0;
virQEMUDriverConfigPtr cfg = NULL; virQEMUDriverConfigPtr cfg = NULL;
@ -16766,13 +16769,14 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
rem.vm = vm; rem.vm = vm;
rem.metadata_only = metadata_only; rem.metadata_only = metadata_only;
rem.err = 0; rem.err = 0;
rem.current = false; rem.current = virDomainSnapshotGetCurrent(vm->snapshots);
virDomainMomentForEachDescendant(snap, rem.found = false;
qemuDomainSnapshotDiscardAll, rem.momentDiscard = qemuDomainSnapshotDiscard;
virDomainMomentForEachDescendant(snap, qemuDomainMomentDiscardAll,
&rem); &rem);
if (rem.err < 0) if (rem.err < 0)
goto endjob; goto endjob;
if (rem.current) { if (rem.found) {
virDomainSnapshotSetCurrent(vm->snapshots, snap); virDomainSnapshotSetCurrent(vm->snapshots, snap);
if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) { if (flags & VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) {
if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps, if (qemuDomainSnapshotWriteMetadata(vm, snap, driver->caps,
@ -16787,14 +16791,15 @@ qemuDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
} }
} }
} else if (snap->nchildren) { } else if (snap->nchildren) {
rep.cfg = cfg; rep.dir = cfg->snapshotDir;
rep.parent = snap->parent; rep.parent = snap->parent;
rep.vm = vm; rep.vm = vm;
rep.err = 0; rep.err = 0;
rep.caps = driver->caps; rep.caps = driver->caps;
rep.xmlopt = driver->xmlopt; rep.xmlopt = driver->xmlopt;
rep.writeMetadata = qemuDomainSnapshotWriteMetadata;
virDomainMomentForEachChild(snap, virDomainMomentForEachChild(snap,
qemuDomainSnapshotReparentChildren, qemuDomainMomentReparentChildren,
&rep); &rep);
if (rep.err < 0) if (rep.err < 0)
goto endjob; goto endjob;