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 noop = Function.prototype
|
||||||
|
|
||||||
|
const INTERRUPTED_VHDS_REG = /^(?:(.+)\/)?\.(.+)\.merge.json$/
|
||||||
const listVhds = async (handler, vmDir) => {
|
const listVhds = async (handler, vmDir) => {
|
||||||
const vhds = []
|
const vhds = []
|
||||||
|
const interruptedVhds = new Set()
|
||||||
|
|
||||||
await asyncMap(
|
await asyncMap(
|
||||||
await handler.list(`${vmDir}/vdis`, {
|
await handler.list(`${vmDir}/vdis`, {
|
||||||
ignoreMissing: true,
|
ignoreMissing: true,
|
||||||
@ -88,16 +91,26 @@ const listVhds = async (handler, vmDir) => {
|
|||||||
await handler.list(jobDir, {
|
await handler.list(jobDir, {
|
||||||
prependDir: true,
|
prependDir: true,
|
||||||
}),
|
}),
|
||||||
async vdiDir =>
|
async vdiDir => {
|
||||||
vhds.push(
|
const list = await handler.list(vdiDir, {
|
||||||
...(await handler.list(vdiDir, {
|
filter: file => isVhdFile(file) || INTERRUPTED_VHDS_REG.test(file),
|
||||||
filter: isVhdFile,
|
prependDir: true,
|
||||||
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 }) {
|
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 vhdParents = { __proto__: null }
|
||||||
const vhdChildren = { __proto__: null }
|
const vhdChildren = { __proto__: null }
|
||||||
|
|
||||||
|
const vhdsList = await listVhds(handler, vmDir)
|
||||||
|
|
||||||
// remove broken VHDs
|
// remove broken VHDs
|
||||||
await asyncMap(await listVhds(handler, vmDir), async path => {
|
await asyncMap(vhdsList.vhds, async path => {
|
||||||
try {
|
try {
|
||||||
const vhd = new Vhd(handler, path)
|
const vhd = new Vhd(handler, path)
|
||||||
await vhd.readHeaderAndFooter()
|
await vhd.readHeaderAndFooter(!vhdsList.interruptedVhds.has(path))
|
||||||
vhds.add(path)
|
vhds.add(path)
|
||||||
if (vhd.footer.diskType === DISK_TYPE_DIFFERENCING) {
|
if (vhd.footer.diskType === DISK_TYPE_DIFFERENCING) {
|
||||||
const parent = resolve('/', dirname(path), vhd.header.parentUnicodeName)
|
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)
|
vhdChainsToMerge[vhd] = getUsedChildChainOrDelete(vhd)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// merge interrupted VHDs
|
||||||
|
if (merge) {
|
||||||
|
vhdsList.interruptedVhds.forEach(parent => {
|
||||||
|
vhdChainsToMerge[parent] = [vhdChildren[parent], parent]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(vhdChainsToMerge).forEach(key => {
|
Object.keys(vhdChainsToMerge).forEach(key => {
|
||||||
const chain = vhdChainsToMerge[key]
|
const chain = vhdChainsToMerge[key]
|
||||||
if (chain !== undefined) {
|
if (chain !== undefined) {
|
||||||
|
@ -29,4 +29,4 @@
|
|||||||
> In case of conflict, the highest (lowest in previous list) `$version` wins.
|
> In case of conflict, the highest (lowest in previous list) `$version` wins.
|
||||||
|
|
||||||
- @xen-orchestra/fs minor
|
- @xen-orchestra/fs minor
|
||||||
- @xen-orchestra/backups patch
|
- @xen-orchestra/backups minor
|
||||||
|
Loading…
Reference in New Issue
Block a user