From 9b34fc369bc098e3d2bf49f1bb1c84fb6b1e5d63 Mon Sep 17 00:00:00 2001 From: badrAZ Date: Wed, 4 Mar 2020 16:07:50 +0100 Subject: [PATCH] fix(@xen-orchestra/fs): fix deadlock between "outputFile" and "mkdir" (#4831) --- @xen-orchestra/fs/src/abstract.js | 27 +++++++++++++++------------ @xen-orchestra/fs/src/fs.spec.js | 6 ++++++ CHANGELOG.unreleased.md | 2 ++ 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/@xen-orchestra/fs/src/abstract.js b/@xen-orchestra/fs/src/abstract.js index b874403b0..6b4efc49c 100644 --- a/@xen-orchestra/fs/src/abstract.js +++ b/@xen-orchestra/fs/src/abstract.js @@ -283,17 +283,7 @@ export default class RemoteHandlerAbstract { } async mkdir(dir: string): Promise { - dir = normalizePath(dir) - try { - await this._mkdir(dir) - } catch (error) { - if (error == null || error.code !== 'EEXIST') { - throw error - } - - // this operation will throw if it's not already a directory - await this._list(dir) - } + await this.__mkdir(normalizePath(dir)) } async mktree(dir: string): Promise { @@ -456,6 +446,19 @@ export default class RemoteHandlerAbstract { await timeout.call(this._closeFile(fd.fd), this._timeout) } + async __mkdir(dir: string): Promise { + try { + await this._mkdir(dir) + } catch (error) { + if (error == null || error.code !== 'EEXIST') { + throw error + } + + // this operation will throw if it's not already a directory + await this._list(dir) + } + } + async __openFile(path: string, flags: string): Promise { path = normalizePath(path) @@ -513,7 +516,7 @@ export default class RemoteHandlerAbstract { async _mktree(dir: string): Promise { try { - return await this.mkdir(dir) + return await this.__mkdir(dir) } catch (error) { if (error.code !== 'ENOENT') { throw error diff --git a/@xen-orchestra/fs/src/fs.spec.js b/@xen-orchestra/fs/src/fs.spec.js index 4a0eec29c..7e726db9b 100644 --- a/@xen-orchestra/fs/src/fs.spec.js +++ b/@xen-orchestra/fs/src/fs.spec.js @@ -219,6 +219,12 @@ handlers.forEach(url => { const error = await rejectionOf(handler.outputFile('file', '')) expect(error.code).toBe('EEXIST') }) + + it("shouldn't timeout in case of the respect of the parallel execution restriction", async () => { + const handler = getHandler({ url }, { maxParallelOperations: 1 }) + await handler.sync() + await handler.outputFile(`xo-fs-tests-${Date.now()}/test`, '') + }, 40) }) describe('#read()', () => { diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 95d3c9316..2da183531 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -15,6 +15,7 @@ - [Backup reports] Fix backup report not sent in case of interrupted backup job (PR [#4772](https://github.com/vatesfr/xen-orchestra/pull/4772)) - Fix TLS error (`unsupported protocol`) with XenServer <= 6.5 and Node >= 12 (PR [#8437](https://github.com/vatesfr/xen-orchestra/pull/8437)) +- [Metadata backup] Fix timeout when lots of pools are backed up [#4819](https://github.com/vatesfr/xen-orchestra/issues/4819) (PR [#4831](https://github.com/vatesfr/xen-orchestra/pull/4831)) ### Released packages @@ -23,6 +24,7 @@ > > Rule of thumb: add packages on top. +- @xen-orchestra/fs v0.10.3 - xen-api v0.28.1 - xo-server-backup-reports v0.16.5 - xo-server v5.58.0