mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
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:
parent
6b90a84738
commit
a487890d37
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user