mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-21 20:15:17 +00:00
qemu_snapshot: move snapshot discard out of qemu_domain.c
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
f5bde47d6c
commit
9dd19a7a43
@ -31,6 +31,7 @@
|
||||
#include "qemu_migration_params.h"
|
||||
#include "qemu_security.h"
|
||||
#include "qemu_slirp.h"
|
||||
#include "qemu_snapshot.h"
|
||||
#include "qemu_extdevice.h"
|
||||
#include "qemu_blockjob.h"
|
||||
#include "qemu_checkpoint.h"
|
||||
@ -7140,81 +7141,6 @@ qemuDomainSnapshotForEachQcow2(virQEMUDriver *driver,
|
||||
op, try_all, def->ndisks);
|
||||
}
|
||||
|
||||
/* Discard one snapshot (or its metadata), without reparenting any children. */
|
||||
int
|
||||
qemuDomainSnapshotDiscard(virQEMUDriver *driver,
|
||||
virDomainObj *vm,
|
||||
virDomainMomentObj *snap,
|
||||
bool update_parent,
|
||||
bool metadata_only)
|
||||
{
|
||||
g_autofree char *snapFile = NULL;
|
||||
qemuDomainObjPrivate *priv;
|
||||
virDomainMomentObj *parentsnap = NULL;
|
||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
||||
|
||||
if (!metadata_only) {
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
size_t i;
|
||||
/* Ignore any skipped disks */
|
||||
|
||||
/* Prefer action on the disks in use at the time the snapshot was
|
||||
* created; but fall back to current definition if dealing with a
|
||||
* snapshot created prior to libvirt 0.9.5. */
|
||||
virDomainDef *def = snap->def->dom;
|
||||
|
||||
if (!def)
|
||||
def = vm->def;
|
||||
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
if (virDomainDiskTranslateSourcePool(def->disks[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemuDomainSnapshotForEachQcow2(driver, def, snap, "-d", true) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
priv = vm->privateData;
|
||||
qemuDomainObjEnterMonitor(vm);
|
||||
/* we continue on even in the face of error */
|
||||
qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
|
||||
qemuDomainObjExitMonitor(vm);
|
||||
}
|
||||
}
|
||||
|
||||
snapFile = g_strdup_printf("%s/%s/%s.xml", cfg->snapshotDir, vm->def->name,
|
||||
snap->def->name);
|
||||
|
||||
if (snap == virDomainSnapshotGetCurrent(vm->snapshots)) {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, NULL);
|
||||
if (update_parent && snap->def->parent_name) {
|
||||
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
|
||||
snap->def->parent_name);
|
||||
if (!parentsnap) {
|
||||
VIR_WARN("missing parent snapshot matching name '%s'",
|
||||
snap->def->parent_name);
|
||||
} else {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, parentsnap);
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, parentsnap,
|
||||
driver->xmlopt,
|
||||
cfg->snapshotDir) < 0) {
|
||||
VIR_WARN("failed to set parent snapshot '%s' as current",
|
||||
snap->def->parent_name);
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unlink(snapFile) < 0)
|
||||
VIR_WARN("Failed to unlink %s", snapFile);
|
||||
if (update_parent)
|
||||
virDomainMomentDropParent(snap);
|
||||
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hash iterator callback to discard multiple snapshots. */
|
||||
int qemuDomainMomentDiscardAll(void *payload,
|
||||
const char *name G_GNUC_UNUSED,
|
||||
@ -7233,23 +7159,6 @@ int qemuDomainMomentDiscardAll(void *payload,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
||||
virDomainObj *vm)
|
||||
{
|
||||
virQEMUMomentRemove rem = {
|
||||
.driver = driver,
|
||||
.vm = vm,
|
||||
.metadata_only = true,
|
||||
.momentDiscard = qemuDomainSnapshotDiscard,
|
||||
};
|
||||
|
||||
virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem);
|
||||
virDomainSnapshotObjListRemoveAll(vm->snapshots);
|
||||
|
||||
return rem.err;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
|
||||
@ -7262,7 +7171,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
|
||||
g_autofree char *chkDir = NULL;
|
||||
|
||||
/* Remove any snapshot metadata prior to removing the domain */
|
||||
if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0) {
|
||||
if (qemuSnapshotDiscardAllMetadata(driver, vm) < 0) {
|
||||
VIR_WARN("unable to remove all snapshots for domain %s",
|
||||
vm->def->name);
|
||||
} else {
|
||||
|
@ -681,12 +681,6 @@ int qemuDomainSnapshotForEachQcow2(virQEMUDriver *driver,
|
||||
const char *op,
|
||||
bool try_all);
|
||||
|
||||
int qemuDomainSnapshotDiscard(virQEMUDriver *driver,
|
||||
virDomainObj *vm,
|
||||
virDomainMomentObj *snap,
|
||||
bool update_current,
|
||||
bool metadata_only);
|
||||
|
||||
typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
|
||||
struct _virQEMUMomentRemove {
|
||||
virQEMUDriver *driver;
|
||||
@ -703,9 +697,6 @@ int qemuDomainMomentDiscardAll(void *payload,
|
||||
const char *name,
|
||||
void *data);
|
||||
|
||||
int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
||||
virDomainObj *vm);
|
||||
|
||||
void qemuDomainRemoveInactive(virQEMUDriver *driver,
|
||||
virDomainObj *vm,
|
||||
virDomainUndefineFlagsValues flags,
|
||||
|
@ -6520,7 +6520,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
||||
nsnapshots);
|
||||
goto endjob;
|
||||
}
|
||||
if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0)
|
||||
if (qemuSnapshotDiscardAllMetadata(driver, vm) < 0)
|
||||
goto endjob;
|
||||
}
|
||||
if (!virDomainObjIsActive(vm) &&
|
||||
|
@ -2281,6 +2281,100 @@ qemuSnapshotChildrenReparent(void *payload,
|
||||
}
|
||||
|
||||
|
||||
/* Discard one snapshot (or its metadata), without reparenting any children. */
|
||||
static int
|
||||
qemuSnapshotDiscard(virQEMUDriver *driver,
|
||||
virDomainObj *vm,
|
||||
virDomainMomentObj *snap,
|
||||
bool update_parent,
|
||||
bool metadata_only)
|
||||
{
|
||||
g_autofree char *snapFile = NULL;
|
||||
qemuDomainObjPrivate *priv;
|
||||
virDomainMomentObj *parentsnap = NULL;
|
||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
||||
|
||||
if (!metadata_only) {
|
||||
if (!virDomainObjIsActive(vm)) {
|
||||
size_t i;
|
||||
/* Ignore any skipped disks */
|
||||
|
||||
/* Prefer action on the disks in use at the time the snapshot was
|
||||
* created; but fall back to current definition if dealing with a
|
||||
* snapshot created prior to libvirt 0.9.5. */
|
||||
virDomainDef *def = snap->def->dom;
|
||||
|
||||
if (!def)
|
||||
def = vm->def;
|
||||
|
||||
for (i = 0; i < def->ndisks; i++) {
|
||||
if (virDomainDiskTranslateSourcePool(def->disks[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (qemuDomainSnapshotForEachQcow2(driver, def, snap, "-d", true) < 0)
|
||||
return -1;
|
||||
} else {
|
||||
priv = vm->privateData;
|
||||
qemuDomainObjEnterMonitor(vm);
|
||||
/* we continue on even in the face of error */
|
||||
qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
|
||||
qemuDomainObjExitMonitor(vm);
|
||||
}
|
||||
}
|
||||
|
||||
snapFile = g_strdup_printf("%s/%s/%s.xml", cfg->snapshotDir, vm->def->name,
|
||||
snap->def->name);
|
||||
|
||||
if (snap == virDomainSnapshotGetCurrent(vm->snapshots)) {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, NULL);
|
||||
if (update_parent && snap->def->parent_name) {
|
||||
parentsnap = virDomainSnapshotFindByName(vm->snapshots,
|
||||
snap->def->parent_name);
|
||||
if (!parentsnap) {
|
||||
VIR_WARN("missing parent snapshot matching name '%s'",
|
||||
snap->def->parent_name);
|
||||
} else {
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, parentsnap);
|
||||
if (qemuDomainSnapshotWriteMetadata(vm, parentsnap,
|
||||
driver->xmlopt,
|
||||
cfg->snapshotDir) < 0) {
|
||||
VIR_WARN("failed to set parent snapshot '%s' as current",
|
||||
snap->def->parent_name);
|
||||
virDomainSnapshotSetCurrent(vm->snapshots, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unlink(snapFile) < 0)
|
||||
VIR_WARN("Failed to unlink %s", snapFile);
|
||||
if (update_parent)
|
||||
virDomainMomentDropParent(snap);
|
||||
virDomainSnapshotObjListRemove(vm->snapshots, snap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
qemuSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
||||
virDomainObj *vm)
|
||||
{
|
||||
virQEMUMomentRemove rem = {
|
||||
.driver = driver,
|
||||
.vm = vm,
|
||||
.metadata_only = true,
|
||||
.momentDiscard = qemuSnapshotDiscard,
|
||||
};
|
||||
|
||||
virDomainSnapshotForEach(vm->snapshots, qemuDomainMomentDiscardAll, &rem);
|
||||
virDomainSnapshotObjListRemoveAll(vm->snapshots);
|
||||
|
||||
return rem.err;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuSnapshotDeleteSingle(virDomainObj *vm,
|
||||
virDomainMomentObj *snap,
|
||||
@ -2307,7 +2401,7 @@ qemuSnapshotDeleteSingle(virDomainObj *vm,
|
||||
virDomainMomentMoveChildren(snap, snap->parent);
|
||||
}
|
||||
|
||||
return qemuDomainSnapshotDiscard(driver, vm, snap, true, metadata_only);
|
||||
return qemuSnapshotDiscard(driver, vm, snap, true, metadata_only);
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,6 +49,10 @@ qemuSnapshotRevert(virDomainObj *vm,
|
||||
virDomainSnapshotPtr snapshot,
|
||||
unsigned int flags);
|
||||
|
||||
int
|
||||
qemuSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
||||
virDomainObj *vm);
|
||||
|
||||
int
|
||||
qemuSnapshotDelete(virDomainObj *vm,
|
||||
virDomainSnapshotPtr snapshot,
|
||||
|
Loading…
x
Reference in New Issue
Block a user