@xen-orchestra/backups 0.71.0 → 0.71.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -56,62 +56,77 @@ export class IncrementalXapiWriter extends MixinXapiWriter(AbstractIncrementalWr
|
|
|
56
56
|
})
|
|
57
57
|
debug('checkBaseVdis, got snapshot candidates,', snapshotCandidates.length)
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
diffDisk = new XapiDiskSource({ xapi: sr.$xapi, vdiRef: activeVdi.$ref, baseRef: snapshot.$ref })
|
|
84
|
-
await diffDisk.init()
|
|
85
|
-
if (diffDisk.getBlockIndexes().length === 0) {
|
|
86
|
-
const sourceUuid = snapshot.other_config?.[COPY_OF]
|
|
87
|
-
if (sourceUuid) {
|
|
88
|
-
this.#baseVdisBySourceUuid.set(sourceUuid, activeVdi)
|
|
59
|
+
if (snapshotCandidates.length > 0) {
|
|
60
|
+
// New snapshot-based flow (6.3+): verify no data was written between
|
|
61
|
+
// the target snapshot and its active VDI.
|
|
62
|
+
let targetVmRef
|
|
63
|
+
let canChainToTargetVm = true
|
|
64
|
+
await asyncEach(
|
|
65
|
+
snapshotCandidates,
|
|
66
|
+
async snapshot => {
|
|
67
|
+
let diffDisk
|
|
68
|
+
try {
|
|
69
|
+
const activeVdi = sr.$xapi.getObject(snapshot.$snapshot_of)
|
|
70
|
+
const userVbds = activeVdi.$VBDs?.filter(vbd => vbd.$VM && !vbd.$VM.is_control_domain) ?? []
|
|
71
|
+
if (userVbds.length !== 1) {
|
|
72
|
+
debug('checkBaseVdis, share vbd ', { ref: snapshot.$ref, userVbds })
|
|
73
|
+
// shared vdi ignore
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
const vm = userVbds[0].$VM
|
|
77
|
+
if (!('start' in vm.blocked_operations)) {
|
|
78
|
+
debug('checkBaseVdis, vm not blocked', { vmRef: vm.$ref })
|
|
79
|
+
// vm start unlocked
|
|
80
|
+
// not really an issue since we have check the delta
|
|
81
|
+
// but it indicates the users played with the blocked operations
|
|
82
|
+
return
|
|
89
83
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
84
|
+
diffDisk = new XapiDiskSource({ xapi: sr.$xapi, vdiRef: activeVdi.$ref, baseRef: snapshot.$ref })
|
|
85
|
+
await diffDisk.init()
|
|
86
|
+
if (diffDisk.getBlockIndexes().length === 0) {
|
|
87
|
+
const sourceUuid = snapshot.other_config?.[COPY_OF]
|
|
88
|
+
if (sourceUuid) {
|
|
89
|
+
this.#baseVdisBySourceUuid.set(sourceUuid, activeVdi)
|
|
90
|
+
}
|
|
91
|
+
// Track the target VM (the replicated VM to update on the next transfer).
|
|
92
|
+
targetVmRef = vm.$ref
|
|
93
|
+
} else {
|
|
94
|
+
// not empty, we will create a new VM
|
|
95
|
+
canChainToTargetVm = false
|
|
96
|
+
debug('checkBaseVdis, data between snapshot and active disk', {
|
|
97
|
+
vdiRef: snapshot.$ref,
|
|
98
|
+
nbBlocks: diffDisk.getBlockIndexes().length,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
debug('checkBaseVdis, skipping snapshot', { ref: snapshot.$ref, error })
|
|
103
|
+
return
|
|
104
|
+
} finally {
|
|
105
|
+
await diffDisk?.close().catch(error => debug('checkBaseVdis, error closing', error))
|
|
99
106
|
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
} finally {
|
|
104
|
-
await diffDisk?.close().catch(error => debug('checkBaseVdis, error closing', error))
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
concurrency: 4,
|
|
105
110
|
}
|
|
106
|
-
|
|
107
|
-
{
|
|
108
|
-
concurrency: 4,
|
|
109
|
-
}
|
|
110
|
-
)
|
|
111
|
+
)
|
|
111
112
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
if (canChainToTargetVm && targetVmRef !== undefined) {
|
|
114
|
+
debug('checkBaseVdis,got a valid vm target', targetVmRef)
|
|
115
|
+
this._targetVmRef = targetVmRef
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
// Legacy fallback (upgrade from pre-6.3): no target snapshots exist yet,
|
|
119
|
+
// look for active (non-snapshot) VDIs with matching COPY_OF, like the old code did.
|
|
120
|
+
debug('checkBaseVdis, no snapshot candidates, falling back to legacy active VDI lookup')
|
|
121
|
+
const legacyVdis = sr.$VDIs.filter(vdi => {
|
|
122
|
+
return vdi?.managed && !vdi?.is_a_snapshot && baseUuidToSrcVdi.has(vdi?.other_config[COPY_OF])
|
|
123
|
+
})
|
|
124
|
+
for (const vdi of legacyVdis) {
|
|
125
|
+
const sourceUuid = vdi.other_config[COPY_OF]
|
|
126
|
+
if (sourceUuid) {
|
|
127
|
+
this.#baseVdisBySourceUuid.set(sourceUuid, vdi)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
for (const uuid of baseUuidToSrcVdi.keys()) {
|