Skip to content

Commit

Permalink
fix(@xen-orchestra/backups): compute size of block based backups
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeauchamp committed Jan 2, 2023
1 parent 1702783 commit fe0b422
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 5 deletions.
7 changes: 4 additions & 3 deletions @xen-orchestra/backups/RemoteAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ class RemoteAdapter {
const handler = this._handler
if (this.#useVhdDirectory()) {
const dataPath = `${dirname(path)}/data/${uuidv4()}.vhd`
await createVhdDirectoryFromStream(handler, dataPath, input, {
const size = await createVhdDirectoryFromStream(handler, dataPath, input, {
concurrency: writeBlockConcurrency,
compression: this.#getCompressionType(),
async validator() {
Expand All @@ -671,13 +671,14 @@ class RemoteAdapter {
nbdClient,
})
await VhdAbstract.createAlias(handler, path, dataPath)
return size
} else {
await this.outputStream(path, input, { checksum, validator })
return this.outputStream(path, input, { checksum, validator })
}
}

async outputStream(path, input, { checksum = true, validator = noop } = {}) {
await this._handler.outputStream(path, input, {
return this._handler.outputStream(path, input, {
checksum,
dirMode: this._dirMode,
async validator() {
Expand Down
2 changes: 1 addition & 1 deletion @xen-orchestra/backups/writers/DeltaBackupWriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ exports.DeltaBackupWriter = class DeltaBackupWriter extends MixinBackupWriter(Ab
}
}

await adapter.writeVhd(path, deltaExport.streams[`${id}.vhd`], {
sizeContainers[`${id}.vhd`].size = await adapter.writeVhd(path, deltaExport.streams[`${id}.vhd`], {
// no checksum for VHDs, because they will be invalidated by
// merges and chainings
checksum: false,
Expand Down
3 changes: 3 additions & 0 deletions @xen-orchestra/fs/src/abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { synchronized } from 'decorator-synchronized'
import { basename, dirname, normalize as normalizePath } from './path'
import { createChecksumStream, validChecksumOfReadStream } from './checksum'
import { DEFAULT_ENCRYPTION_ALGORITHM, _getEncryptor } from './_encryptor'
import { watchStreamSize } from '@xen-orchestra/backups/_watchStreamSize'

const { info, warn } = createLogger('xo:fs:abstract')

Expand Down Expand Up @@ -185,6 +186,7 @@ export default class RemoteHandlerAbstract {
async outputStream(path, input, { checksum = true, dirMode, validator } = {}) {
path = normalizePath(path)
let checksumStream
const container = watchStreamSize(input)

input = this._encryptor.encryptStream(input)
if (checksum) {
Expand All @@ -201,6 +203,7 @@ export default class RemoteHandlerAbstract {
// it is by design to allow checking of encrypted files without the key
await this._outputFile(checksumFile(path), await checksumStream.checksum, { dirMode, flags: 'wx' })
}
return container.size
}

// Free the resources possibly dedicated to put the remote at work, when it
Expand Down
20 changes: 20 additions & 0 deletions packages/vhd-lib/Vhd/VhdAbstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,26 @@ exports.VhdAbstract = class VhdAbstract {
await handler.writeFile(aliasPath, relativePathToTarget)
}

size() {
const { header, batSize } = this
let fileSize = FOOTER_SIZE + HEADER_SIZE + batSize + FOOTER_SIZE /* the footer at the end */

// add parentlocator size
for (let i = 0; i < PARENT_LOCATOR_ENTRIES; i++) {
fileSize += header.parentLocatorEntry[i].platformDataSpace * SECTOR_SIZE
}

// add block size
for (let i = 0; i < header.maxTableEntries; i++) {
if (this.containsBlock(i)) {
fileSize += this.fullBlockSize
}
}

assert.strictEqual(fileSize % SECTOR_SIZE, 0)
return fileSize
}

stream() {
const { footer, batSize } = this
const { ...header } = this.header // copy since we don't ant to modifiy the current header
Expand Down
4 changes: 3 additions & 1 deletion packages/vhd-lib/createVhdDirectoryFromStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const buildVhd = Disposable.wrap(async function* (handler, path, inputStream, {
}
)
await Promise.all([vhd.writeFooter(), vhd.writeHeader(), vhd.writeBlockAllocationTable()])
return vhd.size()
})

exports.createVhdDirectoryFromStream = async function createVhdDirectoryFromStream(
Expand All @@ -47,10 +48,11 @@ exports.createVhdDirectoryFromStream = async function createVhdDirectoryFromStre
{ validator, concurrency = 16, compression, nbdClient } = {}
) {
try {
await buildVhd(handler, path, inputStream, { concurrency, compression, nbdClient })
const size = await buildVhd(handler, path, inputStream, { concurrency, compression, nbdClient })
if (validator !== undefined) {
await validator.call(this, path)
}
return size
} catch (error) {
// cleanup on error
await handler.rmtree(path).catch(warn)
Expand Down

0 comments on commit fe0b422

Please sign in to comment.