mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-05 22:05:47 +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_migration_params.h"
|
||||||
#include "qemu_security.h"
|
#include "qemu_security.h"
|
||||||
#include "qemu_slirp.h"
|
#include "qemu_slirp.h"
|
||||||
|
#include "qemu_snapshot.h"
|
||||||
#include "qemu_extdevice.h"
|
#include "qemu_extdevice.h"
|
||||||
#include "qemu_blockjob.h"
|
#include "qemu_blockjob.h"
|
||||||
#include "qemu_checkpoint.h"
|
#include "qemu_checkpoint.h"
|
||||||
@ -7140,81 +7141,6 @@ qemuDomainSnapshotForEachQcow2(virQEMUDriver *driver,
|
|||||||
op, try_all, def->ndisks);
|
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. */
|
/* Hash iterator callback to discard multiple snapshots. */
|
||||||
int qemuDomainMomentDiscardAll(void *payload,
|
int qemuDomainMomentDiscardAll(void *payload,
|
||||||
const char *name G_GNUC_UNUSED,
|
const char *name G_GNUC_UNUSED,
|
||||||
@ -7233,23 +7159,6 @@ int qemuDomainMomentDiscardAll(void *payload,
|
|||||||
return 0;
|
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
|
static void
|
||||||
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
|
qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
|
||||||
@ -7262,7 +7171,7 @@ qemuDomainRemoveInactiveCommon(virQEMUDriver *driver,
|
|||||||
g_autofree char *chkDir = NULL;
|
g_autofree char *chkDir = NULL;
|
||||||
|
|
||||||
/* Remove any snapshot metadata prior to removing the domain */
|
/* 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",
|
VIR_WARN("unable to remove all snapshots for domain %s",
|
||||||
vm->def->name);
|
vm->def->name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -681,12 +681,6 @@ int qemuDomainSnapshotForEachQcow2(virQEMUDriver *driver,
|
|||||||
const char *op,
|
const char *op,
|
||||||
bool try_all);
|
bool try_all);
|
||||||
|
|
||||||
int qemuDomainSnapshotDiscard(virQEMUDriver *driver,
|
|
||||||
virDomainObj *vm,
|
|
||||||
virDomainMomentObj *snap,
|
|
||||||
bool update_current,
|
|
||||||
bool metadata_only);
|
|
||||||
|
|
||||||
typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
|
typedef struct _virQEMUMomentRemove virQEMUMomentRemove;
|
||||||
struct _virQEMUMomentRemove {
|
struct _virQEMUMomentRemove {
|
||||||
virQEMUDriver *driver;
|
virQEMUDriver *driver;
|
||||||
@ -703,9 +697,6 @@ int qemuDomainMomentDiscardAll(void *payload,
|
|||||||
const char *name,
|
const char *name,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
int qemuDomainSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
|
||||||
virDomainObj *vm);
|
|
||||||
|
|
||||||
void qemuDomainRemoveInactive(virQEMUDriver *driver,
|
void qemuDomainRemoveInactive(virQEMUDriver *driver,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
virDomainUndefineFlagsValues flags,
|
virDomainUndefineFlagsValues flags,
|
||||||
|
@ -6520,7 +6520,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
|||||||
nsnapshots);
|
nsnapshots);
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
if (qemuDomainSnapshotDiscardAllMetadata(driver, vm) < 0)
|
if (qemuSnapshotDiscardAllMetadata(driver, vm) < 0)
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
if (!virDomainObjIsActive(vm) &&
|
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
|
static int
|
||||||
qemuSnapshotDeleteSingle(virDomainObj *vm,
|
qemuSnapshotDeleteSingle(virDomainObj *vm,
|
||||||
virDomainMomentObj *snap,
|
virDomainMomentObj *snap,
|
||||||
@ -2307,7 +2401,7 @@ qemuSnapshotDeleteSingle(virDomainObj *vm,
|
|||||||
virDomainMomentMoveChildren(snap, snap->parent);
|
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,
|
virDomainSnapshotPtr snapshot,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuSnapshotDiscardAllMetadata(virQEMUDriver *driver,
|
||||||
|
virDomainObj *vm);
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuSnapshotDelete(virDomainObj *vm,
|
qemuSnapshotDelete(virDomainObj *vm,
|
||||||
virDomainSnapshotPtr snapshot,
|
virDomainSnapshotPtr snapshot,
|
||||||
|
Loading…
Reference in New Issue
Block a user