Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NC | Config files updates are not isolated. Concurrent updates can override one another #8343

Open
dannyzaken opened this issue Sep 10, 2024 · 0 comments

Comments

@dannyzaken
Copy link
Contributor

Environment info

  • NooBaa Version: 5.17
  • Platform: Non Containerized

Actual behavior

  1. Config file updates are not synchronized, and when performed concurrently on the same file, data corruption can occur.

  2. In most update flows, an object (e.g., a bucket) is read from the config file, then modified, and the complete object is sent to update the config file.

  3. When two such updates occur concurrently, such that both updates read the old data, each modify a different property, and then both attempt to write, the second write will override the first write changes.

  4. a concrete example of two bucket update flows:
    put bucket tagging:

    async put_bucket_tagging(params) {
    try {
    const { name, tagging } = params;
    dbg.log0('BucketSpaceFS.put_bucket_tagging: Bucket name, tagging', name, tagging);
    const bucket = await this.config_fs.get_bucket_by_name(name);
    bucket.tag = tagging;
    await this.config_fs.update_bucket_config_file(bucket);
    } catch (error) {
    throw translate_error_codes(error, entity_enum.BUCKET);
    }
    }

    put bucket encryption:

    async put_bucket_encryption(params) {
    try {
    const { name, encryption } = params;
    dbg.log0('BucketSpaceFS.put_bucket_encryption: Bucket name, encryption', name, encryption);
    const bucket = await this.config_fs.get_bucket_by_name(name);
    bucket.encryption = encryption;
    // in case it is algorithm: 'AES256', the property would be undefined
    await this.config_fs.update_bucket_config_file(bucket);
    } catch (err) {
    throw translate_error_codes(err, entity_enum.BUCKET);
    }
    }

    let's take a look at this sequence for example:

    1. process 1 reads the bucket in line 439
    2. process 2 reads the bucket in line 530
    3. process 1 sets bucket.tag and updates the bucket config files (lines 440-441)
    4. process 2 sets bucket.encryption and updates the bucket files (lines 531-533) with data that doesn't have the bucket.tag that was set in step 3.

Expected behavior

  1. 2 concurrent updates should be isolated from one another

Steps to reproduce

More information - Screenshots / Logs / Other output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant