-
Notifications
You must be signed in to change notification settings - Fork 13
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
feat: flock db dir #500
feat: flock db dir #500
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
@@ -29,6 +29,7 @@ lru = "0.12.3" | |||
libc = "0.2.155" | |||
criterion = { version = "0.3", optional = true } | |||
thread_local = "1.1.8" | |||
fs2 = "0.4.3" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not my favorite, as this doesn't give us much. We don't care about supporting much besides modern Linux and macOS, we don't explicitly target Windows and can just directly use flock
. But I thought for now this is OK and we should reconsider that in #501.
impl Drop for Flock { | ||
fn drop(&mut self) { | ||
if let Err(e) = self.lock_fd.unlock() { | ||
eprintln!("Failed to unlock directory lock: {e}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is the first appearance of eprintln!
in this codebase. Should we finally add tracing
or log
? Or should we just swallow this error? Or leave it as is for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should really only happen very rarely. An eprintln!
seems fine, and it'd at least give an indication of what went wrong that can come back up to us.
Closes #483 This commit aim is to return an error message if another process tries to use the same db directory, which is unsupported according to our assumptions. Note that this uses only advisory locking. It's still possible to mess with the directory and containing files. It's the responsibility of the user to prevent that and failure to do so can and will lead to unexpected behavior.
fs2 was introduced in PR #500, but we actually don't really need that much from it. This commit removes the extra dependency in favor of doing the same directly. I think this is pretty-much equivalent to inlining the code.
fs2 was introduced in PR #500, but we actually don't really need that much from it. This commit removes the extra dependency in favor of doing the same directly. I think this is pretty-much equivalent to inlining the code.
fs2 was introduced in PR #500, but we actually don't really need that much from it. This commit removes the extra dependency in favor of doing the same directly. I think this is pretty-much equivalent to inlining the code.
fs2 was introduced in PR #500, but we actually don't really need that much from it. This commit removes the extra dependency in favor of doing the same directly. I think this is pretty-much equivalent to inlining the code.
fs2 was introduced in PR #500, but we actually don't really need that much from it. This commit removes the extra dependency in favor of doing the same directly. I think this is pretty-much equivalent to inlining the code.
Closes #483
This commit aim is to return an error message if another process tries
to use the same db directory, which is unsupported according to our
assumptions.
Note that this uses only advisory locking. It's still possible to mess
with the directory and containing files. It's the responsibility of the
user to prevent that and failure to do so can and will lead to
unexpected behavior.
Implementation Notes
A couple of words on my research of the problem and the taken approach.
There are mandatory and advisory locking. Mandatory locking is a feature of OS that reserves an exclusive right for a specific program to access a particular file. On Linux, mandatory locking is turned off by default and to be avoided (see this). macOS doesn't support mandatory locking.
The typical way to solve this issue is to use advisory locking. That is, depend on the cooperation between the processes that use the files and directories in question. Obviously, this depends on a good will of those processes and not a ironclad solution.
On Linux, it's possible to lock a directory.
flock
with the fd of the directory open with O_PATH can be used. macOS doesn't support opening fds with O_PATH, so this option is not available. To make the solution cross-platform, I stuck to creating a lock file named.lock
in the DB directory and obtaining an exclusive lock on that.Now, the original TODO and issue (#483) mentions the TOCTOU issues. Namely, the fact that the checking if the db directory exists, opening the db dir, initializing the db, opening the db files are all non-atomic and it's possible that the state of the filesystem has changed between the checks and file opening or creation, which can lead to all sorts of issues.
Proper implementation should probably employ
openat
family of syscalls to avoid some of those, at least on Linux. This all is out-of-scope for this PR and better be addressed on the next big refactoring in one fell swoop, e.g. with #501.