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

File a minor race condition in the backup realm file action #7341

Merged
merged 3 commits into from
Feb 14, 2024

Conversation

tgoyne
Copy link
Member

@tgoyne tgoyne commented Feb 13, 2024

Checking if the destination of a copy exists before trying to copy is a TOCTOU race because the state of the filesystem can change between when we check and when we perform the copy. We should instead just open the target file and not perform the copy if it already existed.

clonefile() is an APFS feature to perform copy-on-write clones of files. This is much faster, and makes it so that the copy and then delete original that we do doesn't consume extra disk space. It's not always supported, so we fall back to manual copying if it fails.

Two of the file action fields weren't actually used for anything.

@tgoyne tgoyne self-assigned this Feb 13, 2024
@cla-bot cla-bot bot added the cla: yes label Feb 13, 2024
Copy link

coveralls-official bot commented Feb 13, 2024

Pull Request Test Coverage Report for Build thomas.goyne_172

Details

  • 50 of 52 (96.15%) changed or added relevant lines in 6 files are covered.
  • 176 unchanged lines in 13 files lost coverage.
  • Overall coverage decreased (-0.04%) to 91.84%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/realm/util/file.cpp 15 17 88.24%
Files with Coverage Reduction New Missed Lines %
src/realm/index_string.cpp 1 87.85%
test/test_index_string.cpp 1 94.13%
test/test_query2.cpp 1 99.08%
src/realm/array_string.cpp 2 88.0%
src/realm/sync/noinst/server/server_history.cpp 2 67.94%
src/realm/object-store/sync/impl/sync_file.cpp 3 87.97%
src/realm/util/assert.hpp 4 87.1%
src/realm/util/serializer.cpp 5 90.03%
src/realm/sync/noinst/server/server.cpp 7 76.67%
src/realm/sync/noinst/client_impl_base.cpp 8 85.57%
Totals Coverage Status
Change from base Build 2036: -0.04%
Covered Lines: 235361
Relevant Lines: 256272

💛 - Coveralls

Copy link
Contributor

@michael-wb michael-wb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -193,6 +193,13 @@ void migrate_to_v7(std::shared_ptr<Realm> old_realm, std::shared_ptr<Realm> real
}
}

void migrate_to_v8(Realm&, Realm& realm)
{
if (auto app_metadata_table = realm.read_group().get_table("class_AppMetadata")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we need to do anything to convert the fileActionMetadata entries to the new format without the partition and identity fields? If so, maybe add a comment somewhere in this function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, removing columns no longer present in the schema is done automatically. It just requires a schema version bump since it's a destructive change.

CHANGELOG.md Show resolved Hide resolved
Checking if the destination exists before copying is a race condition as the
file can be created in between the check and the copy. Instead we should
attempt to copy without overwriting the target if it exists.
@tgoyne tgoyne merged commit d6e52f8 into master Feb 14, 2024
36 checks passed
@tgoyne tgoyne deleted the tg/file-copy-race branch February 14, 2024 21:17
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants