feat(backups/cleanVm): detection of interrupted merges
This commit is contained in:
parent
b590e29608
commit
57ef531be0
@ -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,
|
||||
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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user