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:
Dean Deng
2020-08-19 08:53:12 -07:00
committed by gVisor bot
parent 35dc7fe7e7
commit 33c60b893f
2 changed files with 66 additions and 4 deletions
+14 -2
View File
@@ -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.
+52 -2
View File
@@ -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