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
*
* Copyright (C) 2006-2016 Red Hat, Inc.
* Copyright (C) 2006-2019 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* 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. */
int qemuDomainSnapshotDiscardAll(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *data)
int qemuDomainMomentDiscardAll(void *payload,
const void *name ATTRIBUTE_UNUSED,
void *data)
{
virDomainMomentObjPtr snap = payload;
virQEMUSnapRemovePtr curr = data;
virDomainMomentObjPtr moment = payload;
virQEMUMomentRemovePtr curr = data;
int err;
if (virDomainSnapshotGetCurrent(curr->vm->snapshots) == snap)
curr->current = true;
err = qemuDomainSnapshotDiscard(curr->driver, curr->vm, snap, false,
curr->metadata_only);
if (!curr->found && curr->current == moment)
curr->found = true;
err = curr->momentDiscard(curr->driver, curr->vm, moment, false,
curr->metadata_only);
if (err && !curr->err)
curr->err = err;
return 0;
@ -8671,14 +8671,13 @@ int
qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
virDomainObjPtr vm)
{
virQEMUSnapRemove rem;
virQEMUMomentRemove rem = {
.driver = driver,
.vm = vm,
.metadata_only = true
};
rem.driver = driver;
rem.vm = vm;
rem.metadata_only = true;
rem.err = 0;
virDomainSnapshotForEach(vm->snapshots, qemuDomainSnapshotDiscardAll,
&rem);
virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem);
virDomainSnapshotObjListRemoveAll(vm->snapshots);
return rem.err;

View File

@ -1,7 +1,7 @@
/*
* 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
*
* This library is free software; you can redistribute it and/or
@ -38,6 +38,7 @@
# include "virchrdev.h"
# include "virobject.h"
# include "logging/log_manager.h"
# include "virdomainmomentobjlist.h"
# define QEMU_DOMAIN_FORMAT_LIVE_FLAGS \
(VIR_DOMAIN_XML_SECURE)
@ -698,19 +699,22 @@ int qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
bool update_current,
bool metadata_only);
typedef struct _virQEMUSnapRemove virQEMUSnapRemove;
typedef virQEMUSnapRemove *virQEMUSnapRemovePtr;
struct _virQEMUSnapRemove {
typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
typedef virQEMUMomentRemove *virQEMUMomentRemovePtr;
struct _virQEMUMomentRemove {
virQEMUDriverPtr driver;
virDomainObjPtr vm;
int err;
bool metadata_only;
bool current;
virDomainMomentObjPtr current;
bool found;
int (*momentDiscard)(virQEMUDriverPtr, virDomainObjPtr,
virDomainMomentObjPtr, bool, bool);
};
int qemuDomainSnapshotDiscardAll(void *payload,
const void *name,
void *data);
int qemuDomainMomentDiscardAll(void *payload,
const void *name,
void *data);
int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriverPtr driver,
virDomainObjPtr vm);

View File

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