Bind prepared artifact selection against reclaim
This commit is contained in:
parent
d799cf4837
commit
1bd1d395d9
1 changed files with 209 additions and 21 deletions
|
|
@ -351,6 +351,13 @@ pub fn try_exclusive_flock(file: File) -> io::Result<ExclusiveFileLock> {
|
|||
Ok(ExclusiveFileLock(file))
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Returns an error when the nonblocking shared lock is unavailable.
|
||||
pub fn try_shared_flock(file: File) -> io::Result<SharedFileLock> {
|
||||
flock(file.as_fd(), FlockOperation::NonBlockingLockShared)?;
|
||||
Ok(SharedFileLock(file))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExclusiveFileLock(File);
|
||||
|
||||
|
|
@ -360,6 +367,15 @@ impl AsFd for ExclusiveFileLock {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SharedFileLock(File);
|
||||
|
||||
impl AsFd for SharedFileLock {
|
||||
fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
|
||||
self.0.as_fd()
|
||||
}
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
/// Returns an error unless the replacement and containing directory are synced.
|
||||
pub fn atomic_replace(path: &Path, bytes: &[u8]) -> io::Result<()> {
|
||||
|
|
@ -459,7 +475,7 @@ pub fn require_mount_identity(path: &Path, expected: MountIdentity) -> io::Resul
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::OpenOptions;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::fs::symlink;
|
||||
|
||||
|
|
@ -468,6 +484,7 @@ mod tests {
|
|||
use super::{
|
||||
RegularFileMailbox, atomic_replace, current_mount_identity, namespace_identity,
|
||||
require_mount_identity, require_write_sealed, sealed_memfd, try_exclusive_flock,
|
||||
try_shared_flock,
|
||||
};
|
||||
|
||||
fn test_directory(name: &str) -> std::path::PathBuf {
|
||||
|
|
@ -552,6 +569,21 @@ mod tests {
|
|||
std::fs::remove_dir_all(directory).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_flock_excludes_reclaim_until_every_claim_closes() {
|
||||
let directory = test_directory("shared-flock");
|
||||
let path = directory.join("artifact");
|
||||
std::fs::create_dir(&path).unwrap();
|
||||
let first = try_shared_flock(File::open(&path).unwrap()).unwrap();
|
||||
let second = try_shared_flock(File::open(&path).unwrap()).unwrap();
|
||||
assert!(try_exclusive_flock(File::open(&path).unwrap()).is_err());
|
||||
drop(first);
|
||||
assert!(try_exclusive_flock(File::open(&path).unwrap()).is_err());
|
||||
drop(second);
|
||||
assert!(try_exclusive_flock(File::open(&path).unwrap()).is_ok());
|
||||
std::fs::remove_dir_all(directory).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn namespace_identity_is_stable_for_same_namespace() {
|
||||
let first = namespace_identity(std::path::Path::new("/proc/self/ns/mnt")).unwrap();
|
||||
|
|
|
|||
Loading…
Reference in a new issue