mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Return appropriate errors when file locking is unsuccessful.
test_eintr now passes in the Python runtime tests. Updates #3515. PiperOrigin-RevId: 327441081
This commit is contained in:
+14
-2
@@ -46,7 +46,13 @@ func (fl *FileLocks) LockBSD(uid fslock.UniqueID, t fslock.LockType, block fsloc
|
||||
if fl.bsd.LockRegion(uid, t, fslock.LockRange{0, fslock.LockEOF}, block) {
|
||||
return nil
|
||||
}
|
||||
return syserror.ErrWouldBlock
|
||||
|
||||
// Return an appropriate error for the unsuccessful lock attempt, depending on
|
||||
// whether this is a blocking or non-blocking operation.
|
||||
if block == nil {
|
||||
return syserror.ErrWouldBlock
|
||||
}
|
||||
return syserror.ERESTARTSYS
|
||||
}
|
||||
|
||||
// UnlockBSD releases a BSD-style lock on the entire file.
|
||||
@@ -66,7 +72,13 @@ func (fl *FileLocks) LockPOSIX(ctx context.Context, fd *FileDescription, uid fsl
|
||||
if fl.posix.LockRegion(uid, t, rng, block) {
|
||||
return nil
|
||||
}
|
||||
return syserror.ErrWouldBlock
|
||||
|
||||
// Return an appropriate error for the unsuccessful lock attempt, depending on
|
||||
// whether this is a blocking or non-blocking operation.
|
||||
if block == nil {
|
||||
return syserror.ErrWouldBlock
|
||||
}
|
||||
return syserror.ERESTARTSYS
|
||||
}
|
||||
|
||||
// UnlockPOSIX releases a POSIX-style lock on a file region.
|
||||
|
||||
@@ -185,7 +185,7 @@ TEST_F(FlockTest, TestMultipleHolderSharedExclusive) {
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_F(FlockTest, TestSharedLockFailExclusiveHolder) {
|
||||
TEST_F(FlockTest, TestSharedLockFailExclusiveHolderNonblocking) {
|
||||
// This test will verify that a shared lock is denied while
|
||||
// someone holds an exclusive lock.
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX | LOCK_NB),
|
||||
@@ -203,7 +203,33 @@ TEST_F(FlockTest, TestSharedLockFailExclusiveHolder) {
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolder) {
|
||||
void trivial_handler(int signum) {}
|
||||
|
||||
TEST_F(FlockTest, TestSharedLockFailExclusiveHolderBlocking_NoRandomSave) {
|
||||
const DisableSave ds; // Timing-related.
|
||||
|
||||
// This test will verify that a shared lock is denied while
|
||||
// someone holds an exclusive lock.
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX | LOCK_NB),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(test_file_name_, O_RDWR));
|
||||
|
||||
// Register a signal handler for SIGALRM and set an alarm that will go off
|
||||
// while blocking in the subsequent flock() call. This will interrupt flock()
|
||||
// and cause it to return EINTR.
|
||||
struct sigaction act = {};
|
||||
act.sa_handler = trivial_handler;
|
||||
ASSERT_THAT(sigaction(SIGALRM, &act, NULL), SyscallSucceeds());
|
||||
ASSERT_THAT(ualarm(10000, 0), SyscallSucceeds());
|
||||
ASSERT_THAT(flock(fd.get(), LOCK_SH), SyscallFailsWithErrno(EINTR));
|
||||
|
||||
// Unlock
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolderNonblocking) {
|
||||
// This test will verify that an exclusive lock is denied while
|
||||
// someone already holds an exclsuive lock.
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX | LOCK_NB),
|
||||
@@ -221,6 +247,30 @@ TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolder) {
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_F(FlockTest, TestExclusiveLockFailExclusiveHolderBlocking_NoRandomSave) {
|
||||
const DisableSave ds; // Timing-related.
|
||||
|
||||
// This test will verify that an exclusive lock is denied while
|
||||
// someone already holds an exclsuive lock.
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_EX | LOCK_NB),
|
||||
SyscallSucceedsWithValue(0));
|
||||
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(test_file_name_, O_RDWR));
|
||||
|
||||
// Register a signal handler for SIGALRM and set an alarm that will go off
|
||||
// while blocking in the subsequent flock() call. This will interrupt flock()
|
||||
// and cause it to return EINTR.
|
||||
struct sigaction act = {};
|
||||
act.sa_handler = trivial_handler;
|
||||
ASSERT_THAT(sigaction(SIGALRM, &act, NULL), SyscallSucceeds());
|
||||
ASSERT_THAT(ualarm(10000, 0), SyscallSucceeds());
|
||||
ASSERT_THAT(flock(fd.get(), LOCK_EX), SyscallFailsWithErrno(EINTR));
|
||||
|
||||
// Unlock
|
||||
ASSERT_THAT(flock(test_file_fd_.get(), LOCK_UN), SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
TEST_F(FlockTest, TestMultipleHolderSharedExclusiveUpgrade) {
|
||||
// This test will verify that we cannot obtain an exclusive lock while
|
||||
// a shared lock is held by another descriptor, then verify that an upgrade
|
||||
|
||||
Reference in New Issue
Block a user