From 30215b2fa841256cf8467fe9379c001b4c74b043 Mon Sep 17 00:00:00 2001 From: Romy <35330373+romayalon@users.noreply.github.com> Date: Sun, 9 Mar 2025 18:18:45 +0200 Subject: [PATCH] Fail if locked Signed-off-by: Romy <35330373+romayalon@users.noreply.github.com> --- src/manage_nsfs/manage_nsfs_cli_errors.js | 12 +++++++++++- src/manage_nsfs/nc_lifecycle.js | 2 +- src/native/fs/fs_napi.cpp | 14 +++++++++++++- src/sdk/nb.d.ts | 2 +- src/util/native_fs_utils.js | 10 ++++++++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/manage_nsfs/manage_nsfs_cli_errors.js b/src/manage_nsfs/manage_nsfs_cli_errors.js index 91cf5809b6..9afdb4131e 100644 --- a/src/manage_nsfs/manage_nsfs_cli_errors.js +++ b/src/manage_nsfs/manage_nsfs_cli_errors.js @@ -534,6 +534,15 @@ ManageCLIError.NooBaaServiceIsNotActive = Object.freeze({ http_code: 400, }); +// TEMPORARY - +// currently, only one lifecyle worker process can run at a time +// in the fututre, we will allow multiple workers to run while they are not working on the same buckets +ManageCLIError.LifecyleWorkerAlreadyRunning = Object.freeze({ + code: 'LifecyleWorkerAlreadyRunning', + message: 'Lifecycle worker can not run another lifecyle worker process is already running.', + http_code: 400, +}); + /////////////////////////////// // ERRORS MAPPING // /////////////////////////////// @@ -556,7 +565,8 @@ ManageCLIError.RPC_ERROR_TO_MANAGE = Object.freeze({ NO_SUCH_USER: ManageCLIError.InvalidAccountDistinguishedName, INVALID_MASTER_KEY: ManageCLIError.InvalidMasterKey, INVALID_BUCKET_NAME: ManageCLIError.InvalidBucketName, - CONFIG_DIR_VERSION_MISMATCH: ManageCLIError.ConfigDirUpdateBlocked + CONFIG_DIR_VERSION_MISMATCH: ManageCLIError.ConfigDirUpdateBlocked, + LOCKED: ManageCLIError.LifecyleWorkerAlreadyRunning }); const NSFS_CLI_ERROR_EVENT_MAP = { diff --git a/src/manage_nsfs/nc_lifecycle.js b/src/manage_nsfs/nc_lifecycle.js index f275d14eb8..daea29a656 100644 --- a/src/manage_nsfs/nc_lifecycle.js +++ b/src/manage_nsfs/nc_lifecycle.js @@ -32,7 +32,7 @@ async function run_lifecycle_under_lock(config_fs) { dbg.log0('run_lifecycle_under_lock acquired lock - start lifecycle'); await run_lifecycle(config_fs); dbg.log0('run_lifecycle_under_lock done lifecycle - released lock'); - }); + }, true); } /** diff --git a/src/native/fs/fs_napi.cpp b/src/native/fs/fs_napi.cpp index d1d56d3ab6..c575329fb9 100644 --- a/src/native/fs/fs_napi.cpp +++ b/src/native/fs/fs_napi.cpp @@ -1823,9 +1823,11 @@ struct FileFlock : public FSWrapWorker struct FileFcntlLock : public FSWrapWorker { struct flock fl; + int op; FileFcntlLock(const Napi::CallbackInfo& info) : FSWrapWorker(info) , fl() + , op(F_OFD_SETLKW) { // lock entire file fl.l_whence = SEEK_SET; @@ -1846,6 +1848,16 @@ struct FileFcntlLock : public FSWrapWorker SetError("invalid lock type"); } } + if (info.Length() > 2 && !info[2].IsUndefined()) { + auto op_string = info[2].As().Utf8Value(); + if (op_string == "THROW") { + op = F_OFD_SETLK; + } else if (op_string == "WAIT") { + op = F_OFD_SETLKW; + } else { + SetError("invalid lock operation"); + } + } Begin(XSTR() << "FileFcntlLock" << DVAL(_wrap->_path)); } @@ -1855,7 +1867,7 @@ struct FileFcntlLock : public FSWrapWorker CHECK_WRAP_FD(fd); // This uses F_OFD_SETLKW instead for discussion related to this choice // refer: https://github.com/noobaa/noobaa-core/pull/8174 - SYSCALL_OR_RETURN(fcntl(fd, F_OFD_SETLKW, &fl)); + SYSCALL_OR_RETURN(fcntl(fd, op, &fl)); } }; diff --git a/src/sdk/nb.d.ts b/src/sdk/nb.d.ts index 2a2e3396b8..82ddb01d57 100644 --- a/src/sdk/nb.d.ts +++ b/src/sdk/nb.d.ts @@ -1017,7 +1017,7 @@ interface NativeFile { fsync(fs_context: NativeFSContext): Promise; fd: number; flock(fs_context: NativeFSContext, operation: "EXCLUSIVE" | "SHARED" | "UNLOCK"): Promise; - fcntllock(fs_context: NativeFSContext, operation: "EXCLUSIVE" | "SHARED" | "UNLOCK"): Promise; + fcntllock(fs_context: NativeFSContext, type: "EXCLUSIVE" | "SHARED" | "UNLOCK", op?: "THROW" | "WAIT"): Promise; } interface NativeDir { diff --git a/src/util/native_fs_utils.js b/src/util/native_fs_utils.js index 20eda707b8..f703018125 100644 --- a/src/util/native_fs_utils.js +++ b/src/util/native_fs_utils.js @@ -718,13 +718,19 @@ function translate_error_codes(err, entity) { * @param {nb.NativeFSContext} fs_context * @param {string} lock_path * @param {Function} cb + * @param {boolean} [throw_if_locked] */ -async function lock_and_run(fs_context, lock_path, cb) { +async function lock_and_run(fs_context, lock_path, cb, throw_if_locked = false) { const lockfd = await nb_native().fs.open(fs_context, lock_path, 'w'); try { - await lockfd.fcntllock(fs_context, 'EXCLUSIVE'); + await lockfd.fcntllock(fs_context, 'EXCLUSIVE', throw_if_locked ? 'THROW' : undefined); await cb(); + } catch (err) { + dbg.error('lock_and_run: error', err); + if (err.code === 'EAGAIN' && throw_if_locked) { + throw new RpcError('LOCKED', `Resource is locked - lock path= ${lock_path}`); + } } finally { await lockfd.close(fs_context); }