From b2813d7cc031f293c3f91ce153fd2da6011d651f Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Thu, 7 Feb 2019 17:37:09 +0100 Subject: [PATCH] feat(xo-server/snapshotVm): detect and destroy broken quiesced snapshots (#3937) Fixes #3936 --- CHANGELOG.unreleased.md | 1 + packages/xo-server/src/xapi/index.js | 32 ++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 5e1bd5134..acb701adc 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -4,6 +4,7 @@ - [Home] Set description on bulk snapshot [#3925](https://github.com/vatesfr/xen-orchestra/issues/3925) (PR [#3933](https://github.com/vatesfr/xen-orchestra/pull/3933)) - Work-around the XenServer issue when `VBD#VDI` is an empty string instead of an opaque reference (PR [#3950](https://github.com/vatesfr/xen-orchestra/pull/3950)) +- [VM Snapshotting] Detect and destroy broken quiesced snapshot left by XenServer [#3936](https://github.com/vatesfr/xen-orchestra/issues/3936) (PR [#3937](https://github.com/vatesfr/xen-orchestra/pull/3937)) ### Bug fixes diff --git a/packages/xo-server/src/xapi/index.js b/packages/xo-server/src/xapi/index.js index cb030ae66..26c9561f6 100644 --- a/packages/xo-server/src/xapi/index.js +++ b/packages/xo-server/src/xapi/index.js @@ -1545,14 +1545,16 @@ export default class Xapi extends XapiBase { }` ) + const vmRef = vm.$ref let ref do { if (!vm.tags.includes('xo-disable-quiesce')) { + vm = await this.barrier(vmRef) try { ref = await this.callAsync( $cancelToken, 'VM.snapshot_with_quiesce', - vm.$ref, + vmRef, nameLabel ).then(extractOpaqueRef) this.addTag(ref, 'quiesce')::ignoreErrors() @@ -1561,12 +1563,30 @@ export default class Xapi extends XapiBase { } catch (error) { const { code } = error if ( - code !== 'VM_SNAPSHOT_WITH_QUIESCE_NOT_SUPPORTED' && - // quiesce only work on a running VM - code !== 'VM_BAD_POWER_STATE' && // quiesce failed, fallback on standard snapshot // TODO: emit warning - code !== 'VM_SNAPSHOT_WITH_QUIESCE_FAILED' + code === 'VM_SNAPSHOT_WITH_QUIESCE_FAILED' + ) { + // detect and remove new broken snapshots + // + // see https://github.com/vatesfr/xen-orchestra/issues/3936 + const prevSnapshotRefs = new Set(vm.snapshots) + const snapshotNameLabelPrefix = `Snapshot of ${vm.uuid} [` + vm = await this.barrier(vmRef) + const createdSnapshots = vm.$snapshots.filter( + _ => + !prevSnapshotRefs.has(_.$ref) && + _.name_label.startsWith(snapshotNameLabelPrefix) + ) + + // be safe: only delete if there was a single match + if (createdSnapshots.length === 1) { + ignoreErrors.call(this._deleteVm(createdSnapshots[0])) + } + } else if ( + code !== 'VM_SNAPSHOT_WITH_QUIESCE_NOT_SUPPORTED' && + // quiesce only work on a running VM + code !== 'VM_BAD_POWER_STATE' ) { throw error } @@ -1575,7 +1595,7 @@ export default class Xapi extends XapiBase { ref = await this.callAsync( $cancelToken, 'VM.snapshot', - vm.$ref, + vmRef, nameLabel ).then(extractOpaqueRef) } while (false)