fix(xo-server/backups): no checksum files for VHDs (#2761)

Because keeping them up-to-date after chainings and merges is too expensive (requires reading the whole file).

In legacy backups they were keeping up-to-date and great costs and never used for verification anyway.
This commit is contained in:
Julien Fontanet 2018-03-16 16:24:25 +01:00 committed by GitHub
parent 474a765e1b
commit 433f445e99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 64 deletions

View File

@ -283,19 +283,20 @@ async function waitAll<T> (
const writeStream = async (
input: Readable | Promise<Readable>,
handler: RemoteHandler,
path: string
path: string,
{ checksum = true }: { checksum?: boolean } = {}
): Promise<void> => {
input = await input
const tmpPath = `${dirname(path)}/.${basename(path)}`
const output = await handler.createOutputStream(tmpPath, { checksum: true })
const output = await handler.createOutputStream(tmpPath, { checksum })
try {
input.pipe(output)
await output.checksumWritten
// $FlowFixMe
await input.task
await handler.rename(tmpPath, path, { checksum: true })
await handler.rename(tmpPath, path, { checksum })
} catch (error) {
await handler.unlink(tmpPath)
await handler.unlink(tmpPath, { checksum })
throw error
}
}
@ -311,8 +312,7 @@ const writeStream = async (
// │ └─ <job UUID>
// │ └─ <VDI UUID>
// │ ├─ index.json // TODO
// │ ├─ <YYYYMMDD>T<HHmmss>.vhd
// │ └─ <YYYYMMDD>T<HHmmss>.vhd.checksum (only for deltas)
// │ └─ <YYYYMMDD>T<HHmmss>.vhd
// ├─ <YYYYMMDD>T<HHmmss>.json // backup metadata
// ├─ <YYYYMMDD>T<HHmmss>.xva
// └─ <YYYYMMDD>T<HHmmss>.xva.checksum
@ -929,7 +929,16 @@ export default class BackupNg {
parentPath = `${vdiDir}/${parent}`
}
await writeStream(fork.streams[`${id}.vhd`](), handler, path)
await writeStream(
fork.streams[`${id}.vhd`](),
handler,
path,
{
// no checksum for VHDs, because they will be invalidated by
// merges and chainings
checksum: false,
}
)
$defer.onFailure.call(handler, 'unlink', path)
if (isDelta) {
@ -1062,16 +1071,8 @@ export default class BackupNg {
$defer.onFailure.call(handler, 'unlink', path)
const childPath = child.path
await Promise.all([
mergeVhd(handler, path, handler, childPath),
handler.unlink(path + '.checksum'),
])
await Promise.all([
handler.rename(path, childPath),
handler.unlink(childPath + '.checksum'),
])
await mergeVhd(handler, path, handler, childPath)
await handler.rename(path, childPath)
}
async _deleteVms (xapi: Xapi, vms: Vm[]): Promise<void> {

View File

@ -101,30 +101,6 @@ const getDeltaBackupNameWithoutExt = name =>
name.slice(0, -DELTA_BACKUP_EXT_LENGTH)
const isDeltaBackup = name => endsWith(name, DELTA_BACKUP_EXT)
// Checksums have been corrupted between 5.2.6 and 5.2.7.
//
// For a short period of time, bad checksums will be regenerated
// instead of rejected.
//
// TODO: restore when enough time has passed (a week/a month).
async function checkFileIntegrity (handler, name) {
await handler.refreshChecksum(name)
// let stream
//
// try {
// stream = await handler.createReadStream(name, { checksum: true })
// } catch (error) {
// if (error.code === 'ENOENT') {
// return
// }
//
// throw error
// }
//
// stream.resume()
// await fromEvent(stream, 'finish')
}
// -------------------------------------------------------------------
const listPartitions = (() => {
@ -545,15 +521,7 @@ export default class {
const backups = await this._listVdiBackups(handler, dir)
for (let i = 1; i < backups.length; i++) {
const childPath = dir + '/' + backups[i]
const modified = await chainVhd(
handler,
dir + '/' + backups[i - 1],
handler,
childPath
)
if (modified) {
await handler.refreshChecksum(childPath)
}
await chainVhd(handler, dir + '/' + backups[i - 1], handler, childPath)
}
}
@ -569,8 +537,6 @@ export default class {
const timestamp = getVdiTimestamp(backups[i])
const newFullBackup = `${dir}/${timestamp}_full.vhd`
await checkFileIntegrity(handler, `${dir}/${backups[i]}`)
let j = i
for (; j > 0 && isDeltaVdiBackup(backups[j]); j--);
const fullBackupId = j
@ -585,7 +551,6 @@ export default class {
const backup = `${dir}/${backups[j]}`
try {
await checkFileIntegrity(handler, backup)
mergedDataSize += await vhdMerge(handler, parent, handler, backup)
} catch (e) {
console.error('Unable to use vhd-util.', e)
@ -666,13 +631,7 @@ export default class {
const sizeStream = createSizeStream()
try {
const targetStream = await handler.createOutputStream(backupFullPath, {
// FIXME: Checksum is not computed for full vdi backups.
// The problem is in the merge case, a delta merged in a full vdi
// backup forces us to browse the resulting file =>
// Significant transfer time on the network !
checksum: !isFull,
})
const targetStream = await handler.createOutputStream(backupFullPath)
stream.on('error', error => targetStream.emit('error', error))
@ -889,10 +848,7 @@ export default class {
streams[`${id}.vhd`] = await Promise.all(
mapToArray(backups, async backup =>
handler.createReadStream(`${vdisFolder}/${backup}`, {
checksum: true,
ignoreMissingChecksum: true,
})
handler.createReadStream(`${vdisFolder}/${backup}`)
)
)
})