mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 07:59:00 +00:00
snapshot: prevent stranding snapshot data on domain destruction
Just as leaving managed save metadata behind can cause problems when creating a new domain that happens to collide with the name of the just-deleted domain, the same is true of leaving any snapshot metadata behind. For safety sake, extend the semantic change of commit b26a9fa9 to also cover snapshot metadata as a reason to reject undefining an inactive domain. A future patch will make sure that shutdown of a transient domain automatically deletes snapshot metadata (whether by destroy, shutdown, or guest-initiated action). Management apps of transient domains should take care to capture xml of snapshots, if it is necessary to recreate the snapshot metadata on a later transient domain with the same name and uuid. This also documents a new flag that hypervisors can choose to support as a shortcut for taking care of the metadata as part of the undefine process; however, nontrivial driver support for these flags will be deferred to future patches. Note that ESX and VBox can never be transient; therefore, they do not have to worry about automatic cleanup after shutdown (the persistent domain still remains); likewise they never store snapshot metadata, so the undefine flag is trivial. The nontrivial work remaining is thus in the qemu driver. * include/libvirt/libvirt.h.in (VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA): New flag. * src/libvirt.c (virDomainUndefine, virDomainUndefineFlags): Document new limitations and flag. * src/esx/esx_driver.c (esxDomainUndefineFlags): Trivial implementation. * src/vbox/vbox_tmpl.c (vboxDomainUndefineFlags): Likewise. * src/qemu/qemu_driver.c (qemuDomainUndefineFlags): Enforce the limitations.
This commit is contained in:
parent
bd18b9670f
commit
282fe1f08c
@ -923,10 +923,12 @@ virConnectPtr virDomainGetConnect (virDomainPtr domain);
|
||||
* Domain creation and destruction
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* typedef enum {
|
||||
* } virDomainDestroyFlagsValues;
|
||||
*/
|
||||
|
||||
virDomainPtr virDomainCreateXML (virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
@ -1247,7 +1249,11 @@ virDomainPtr virDomainDefineXML (virConnectPtr conn,
|
||||
int virDomainUndefine (virDomainPtr domain);
|
||||
|
||||
typedef enum {
|
||||
VIR_DOMAIN_UNDEFINE_MANAGED_SAVE = (1 << 0),
|
||||
VIR_DOMAIN_UNDEFINE_MANAGED_SAVE = (1 << 0), /* Also remove any
|
||||
managed save */
|
||||
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA = (1 << 1), /* If last use of domain,
|
||||
then also remove any
|
||||
snapshot metadata */
|
||||
|
||||
/* Future undefine control flags should come here. */
|
||||
} virDomainUndefineFlagsValues;
|
||||
|
@ -3309,7 +3309,10 @@ esxDomainUndefineFlags(virDomainPtr domain,
|
||||
esxVI_String *propertyNameList = NULL;
|
||||
esxVI_VirtualMachinePowerState powerState;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
/* No managed save, so we explicitly reject
|
||||
* VIR_DOMAIN_UNDEFINE_MANAGED_SAVE. No snapshot metadata for
|
||||
* ESX, so we can trivially ignore that flag. */
|
||||
virCheckFlags(VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
|
||||
|
||||
if (priv->vCenter != NULL) {
|
||||
ctx = priv->vCenter;
|
||||
|
@ -2058,6 +2058,10 @@ error:
|
||||
* does not free the associated virDomainPtr object.
|
||||
* This function may require privileged access
|
||||
*
|
||||
* If the domain is transient and has any snapshot metadata (see
|
||||
* virDomainSnapshotNum()), then that metadata will automatically
|
||||
* be deleted when the domain quits.
|
||||
*
|
||||
* Returns 0 in case of success and -1 in case of failure.
|
||||
*/
|
||||
int
|
||||
@ -2107,7 +2111,9 @@ error:
|
||||
* This function may require privileged access.
|
||||
*
|
||||
* Calling this function with no @flags set (equal to zero)
|
||||
* is equivalent to calling virDomainDestroy.
|
||||
* is equivalent to calling virDomainDestroy. Using virDomainShutdown()
|
||||
* may produce cleaner results for the guest's disks, but depends on guest
|
||||
* support.
|
||||
*
|
||||
* Returns 0 in case of success and -1 in case of failure.
|
||||
*/
|
||||
@ -2912,12 +2918,17 @@ error:
|
||||
* virDomainShutdown:
|
||||
* @domain: a domain object
|
||||
*
|
||||
* Shutdown a domain, the domain object is still usable there after but
|
||||
* Shutdown a domain, the domain object is still usable thereafter but
|
||||
* the domain OS is being stopped. Note that the guest OS may ignore the
|
||||
* request.
|
||||
* request. For guests that react to a shutdown request, the differences
|
||||
* from virDomainDestroy() are that the guests disk storage will be in a
|
||||
* stable state rather than having the (virtual) power cord pulled, and
|
||||
* this command returns as soon as the shutdown request is issued rather
|
||||
* than blocking until the guest is no longer running.
|
||||
*
|
||||
* TODO: should we add an option for reboot, knowing it may not be doable
|
||||
* in the general case ?
|
||||
* If the domain is transient and has any snapshot metadata (see
|
||||
* virDomainSnapshotNum()), then that metadata will automatically
|
||||
* be deleted when the domain quits.
|
||||
*
|
||||
* Returns 0 in case of success and -1 in case of failure.
|
||||
*/
|
||||
@ -6879,8 +6890,9 @@ error:
|
||||
* the domain configuration is removed.
|
||||
*
|
||||
* If the domain has a managed save image (see
|
||||
* virDomainHasManagedSaveImage()), then the undefine will fail. See
|
||||
* virDomainUndefineFlags() for more control.
|
||||
* virDomainHasManagedSaveImage()), or if it is inactive and has any
|
||||
* snapshot metadata (see virDomainSnapshotNum()), then the undefine will
|
||||
* fail. See virDomainUndefineFlags() for more control.
|
||||
*
|
||||
* Returns 0 in case of success, -1 in case of error
|
||||
*/
|
||||
@ -6931,6 +6943,15 @@ error:
|
||||
* then including VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in @flags will also remove
|
||||
* that file, and omitting the flag will cause the undefine process to fail.
|
||||
*
|
||||
* If the domain is inactive and has any snapshot metadata (see
|
||||
* virDomainSnapshotNum()), then including
|
||||
* VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA in @flags will also remove
|
||||
* that metadata. Omitting the flag will cause the undefine of an
|
||||
* inactive domain to fail. Active snapshots will retain snapshot
|
||||
* metadata until the (now-transient) domain halts, regardless of
|
||||
* whether this flag is present. On hypervisors where snapshots do
|
||||
* not use libvirt metadata, this flag has no effect.
|
||||
*
|
||||
* Returns 0 in case of success, -1 in case of error
|
||||
*/
|
||||
int
|
||||
|
@ -4838,6 +4838,7 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
||||
virDomainEventPtr event = NULL;
|
||||
char *name = NULL;
|
||||
int ret = -1;
|
||||
int nsnapshots;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE, -1);
|
||||
|
||||
@ -4852,6 +4853,14 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!virDomainObjIsActive(vm) &&
|
||||
(nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
|
||||
qemuReportError(VIR_ERR_OPERATION_INVALID,
|
||||
_("cannot delete inactive domain with %d snapshots"),
|
||||
nsnapshots);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!vm->persistent) {
|
||||
qemuReportError(VIR_ERR_OPERATION_INVALID,
|
||||
"%s", _("cannot undefine transient domain"));
|
||||
|
@ -4982,7 +4982,10 @@ vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags)
|
||||
#if VBOX_API_VERSION >= 4000
|
||||
vboxArray media = VBOX_ARRAY_INITIALIZER;
|
||||
#endif
|
||||
virCheckFlags(0, -1);
|
||||
/* No managed save, so we explicitly reject
|
||||
* VIR_DOMAIN_UNDEFINE_MANAGED_SAVE. No snapshot metadata for
|
||||
* VBox, so we can trivially ignore that flag. */
|
||||
virCheckFlags(VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
|
||||
|
||||
vboxIIDFromUUID(&iid, dom->uuid);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user