feat(backups/cleanVm): detection of interrupted merges

This commit is contained in:
badrAZ 2021-04-30 11:43:21 +02:00 committed by Julien Fontanet
parent b590e29608
commit 57ef531be0
2 changed files with 33 additions and 11 deletions

View File

@ -76,8 +76,11 @@ const mergeVhdChain = limitConcurrency(1)(async function mergeVhdChain(chain, {
const noop = Function.prototype
const INTERRUPTED_VHDS_REG = /^(?:(.+)\/)?\.(.+)\.merge.json$/
const listVhds = async (handler, vmDir) => {
const vhds = []
const interruptedVhds = new Set()
await asyncMap(
await handler.list(`${vmDir}/vdis`, {
ignoreMissing: true,
@ -88,16 +91,26 @@ const listVhds = async (handler, vmDir) => {
await handler.list(jobDir, {
prependDir: true,
}),
async vdiDir =>
vhds.push(
...(await handler.list(vdiDir, {
filter: isVhdFile,
prependDir: true,
}))
)
async vdiDir => {
const list = await handler.list(vdiDir, {
filter: file => isVhdFile(file) || INTERRUPTED_VHDS_REG.test(file),
prependDir: true,
})
list.forEach(file => {
const res = INTERRUPTED_VHDS_REG.exec(file)
if (res === null) {
vhds.push(file)
} else {
const [, dir, file] = res
interruptedVhds.add(`${dir}/${file}`)
}
})
}
)
)
return vhds
return { vhds, interruptedVhds }
}
exports.cleanVm = async function cleanVm(vmDir, { remove, merge, onLog = noop }) {
@ -107,11 +120,13 @@ exports.cleanVm = async function cleanVm(vmDir, { remove, merge, onLog = noop })
const vhdParents = { __proto__: null }
const vhdChildren = { __proto__: null }
const vhdsList = await listVhds(handler, vmDir)
// remove broken VHDs
await asyncMap(await listVhds(handler, vmDir), async path => {
await asyncMap(vhdsList.vhds, async path => {
try {
const vhd = new Vhd(handler, path)
await vhd.readHeaderAndFooter()
await vhd.readHeaderAndFooter(!vhdsList.interruptedVhds.has(path))
vhds.add(path)
if (vhd.footer.diskType === DISK_TYPE_DIFFERENCING) {
const parent = resolve('/', dirname(path), vhd.header.parentUnicodeName)
@ -279,6 +294,13 @@ exports.cleanVm = async function cleanVm(vmDir, { remove, merge, onLog = noop })
vhdChainsToMerge[vhd] = getUsedChildChainOrDelete(vhd)
})
// merge interrupted VHDs
if (merge) {
vhdsList.interruptedVhds.forEach(parent => {
vhdChainsToMerge[parent] = [vhdChildren[parent], parent]
})
}
Object.keys(vhdChainsToMerge).forEach(key => {
const chain = vhdChainsToMerge[key]
if (chain !== undefined) {

View File

@ -29,4 +29,4 @@
> In case of conflict, the highest (lowest in previous list) `$version` wins.
- @xen-orchestra/fs minor
- @xen-orchestra/backups patch
- @xen-orchestra/backups minor