mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Remove splice-to/from-weird-files tests.
These tests are permanently broken on Linux after 36e2c7421f02 "fs: don't allow splice read/write without explicit ops". PiperOrigin-RevId: 394161079
This commit is contained in:
@@ -149,31 +149,6 @@ TEST(EventfdTest, BigWriteBigRead) {
|
||||
EXPECT_EQ(l[0], 1);
|
||||
}
|
||||
|
||||
TEST(EventfdTest, SpliceFromPipePartialSucceeds) {
|
||||
int pipes[2];
|
||||
ASSERT_THAT(pipe2(pipes, O_NONBLOCK), SyscallSucceeds());
|
||||
const FileDescriptor pipe_rfd(pipes[0]);
|
||||
const FileDescriptor pipe_wfd(pipes[1]);
|
||||
constexpr uint64_t kVal{1};
|
||||
|
||||
FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_NONBLOCK));
|
||||
|
||||
uint64_t event_array[2];
|
||||
event_array[0] = kVal;
|
||||
event_array[1] = kVal;
|
||||
ASSERT_THAT(write(pipe_wfd.get(), event_array, sizeof(event_array)),
|
||||
SyscallSucceedsWithValue(sizeof(event_array)));
|
||||
EXPECT_THAT(splice(pipe_rfd.get(), /*__offin=*/nullptr, efd.get(),
|
||||
/*__offout=*/nullptr, sizeof(event_array[0]) + 1,
|
||||
SPLICE_F_NONBLOCK),
|
||||
SyscallSucceedsWithValue(sizeof(event_array[0])));
|
||||
|
||||
uint64_t val;
|
||||
ASSERT_THAT(read(efd.get(), &val, sizeof(val)),
|
||||
SyscallSucceedsWithValue(sizeof(val)));
|
||||
EXPECT_EQ(val, kVal);
|
||||
}
|
||||
|
||||
// NotifyNonZero is inherently racy, so random save is disabled.
|
||||
TEST(EventfdTest, NotifyNonZero) {
|
||||
// Waits will time out at 10 seconds.
|
||||
|
||||
@@ -1849,34 +1849,6 @@ TEST(Inotify, SpliceOnWatchTarget) {
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(Inotify, SpliceOnInotifyFD) {
|
||||
int pipefds[2];
|
||||
ASSERT_THAT(pipe2(pipefds, O_NONBLOCK), SyscallSucceeds());
|
||||
|
||||
const TempPath root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
const FileDescriptor fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(InotifyInit1(IN_NONBLOCK));
|
||||
const TempPath file1 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
root.path(), "some content", TempPath::kDefaultFileMode));
|
||||
|
||||
const FileDescriptor file1_fd =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(file1.path(), O_RDONLY));
|
||||
const int watcher = ASSERT_NO_ERRNO_AND_VALUE(
|
||||
InotifyAddWatch(fd.get(), file1.path(), IN_ALL_EVENTS));
|
||||
|
||||
char buf;
|
||||
EXPECT_THAT(read(file1_fd.get(), &buf, 1), SyscallSucceeds());
|
||||
|
||||
EXPECT_THAT(splice(fd.get(), nullptr, pipefds[1], nullptr,
|
||||
sizeof(struct inotify_event) + 1, SPLICE_F_NONBLOCK),
|
||||
SyscallSucceedsWithValue(sizeof(struct inotify_event)));
|
||||
|
||||
const FileDescriptor read_fd(pipefds[0]);
|
||||
const std::vector<Event> events =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(DrainEvents(read_fd.get()));
|
||||
ASSERT_THAT(events, Are({Event(IN_ACCESS, watcher)}));
|
||||
}
|
||||
|
||||
// Watches on a parent should not be triggered by actions on a hard link to one
|
||||
// of its children that has a different parent.
|
||||
TEST(Inotify, LinkOnOtherParent) {
|
||||
|
||||
@@ -208,38 +208,6 @@ TEST(SendFileTest, SendAndUpdateFileOffset) {
|
||||
absl::string_view(actual, kHalfDataSize));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendToDevZeroAndUpdateFileOffset) {
|
||||
// Create temp files.
|
||||
// Test input string length must be > 2 AND even.
|
||||
constexpr char kData[] = "The slings and arrows of outrageous fortune,";
|
||||
constexpr int kDataSize = sizeof(kData) - 1;
|
||||
constexpr int kHalfDataSize = kDataSize / 2;
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), kData, TempPath::kDefaultFileMode));
|
||||
|
||||
// Open the input file as read only.
|
||||
const FileDescriptor inf =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDONLY));
|
||||
|
||||
// Open /dev/zero as write only.
|
||||
const FileDescriptor outf =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_WRONLY));
|
||||
|
||||
// Send data and verify that sendfile returns the correct value.
|
||||
int bytes_sent;
|
||||
EXPECT_THAT(
|
||||
bytes_sent = sendfile(outf.get(), inf.get(), nullptr, kHalfDataSize),
|
||||
SyscallSucceedsWithValue(kHalfDataSize));
|
||||
|
||||
char actual[kHalfDataSize];
|
||||
// Verify that the input file offset has been updated.
|
||||
ASSERT_THAT(read(inf.get(), &actual, kDataSize - bytes_sent),
|
||||
SyscallSucceedsWithValue(kHalfDataSize));
|
||||
EXPECT_EQ(
|
||||
absl::string_view(kData + kDataSize - bytes_sent, kDataSize - bytes_sent),
|
||||
absl::string_view(actual, kHalfDataSize));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendAndUpdateFileOffsetFromNonzeroStartingPoint) {
|
||||
// Create temp files.
|
||||
// Test input string length must be > 2 AND divisible by 4.
|
||||
@@ -609,23 +577,6 @@ TEST(SendFileTest, SendPipeBlocks) {
|
||||
SyscallSucceedsWithValue(kDataSize));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendToSpecialFile) {
|
||||
// Create temp file.
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
|
||||
GetAbsoluteTestTmpdir(), "", TempPath::kDefaultFileMode));
|
||||
|
||||
const FileDescriptor inf =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open(in_file.path(), O_RDWR));
|
||||
constexpr int kSize = 0x7ff;
|
||||
ASSERT_THAT(ftruncate(inf.get(), kSize), SyscallSucceeds());
|
||||
|
||||
auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
|
||||
|
||||
// eventfd can accept a number of bytes which is a multiple of 8.
|
||||
EXPECT_THAT(sendfile(eventfd.get(), inf.get(), nullptr, 0xfffff),
|
||||
SyscallSucceedsWithValue(kSize & (~7)));
|
||||
}
|
||||
|
||||
TEST(SendFileTest, SendFileToPipe) {
|
||||
// Create temp file.
|
||||
constexpr char kData[] = "<insert-quote-here>";
|
||||
@@ -672,57 +623,6 @@ TEST(SendFileTest, SendFileToSelf) {
|
||||
SyscallSucceedsWithValue(kSendfileSize));
|
||||
}
|
||||
|
||||
static volatile int signaled = 0;
|
||||
void SigUsr1Handler(int sig, siginfo_t* info, void* context) { signaled = 1; }
|
||||
|
||||
TEST(SendFileTest, ToEventFDDoesNotSpin) {
|
||||
FileDescriptor efd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
|
||||
|
||||
// Write the maximum value of an eventfd to a file.
|
||||
const uint64_t kMaxEventfdValue = 0xfffffffffffffffe;
|
||||
const auto tempfile = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
const auto tempfd = ASSERT_NO_ERRNO_AND_VALUE(Open(tempfile.path(), O_RDWR));
|
||||
ASSERT_THAT(
|
||||
pwrite(tempfd.get(), &kMaxEventfdValue, sizeof(kMaxEventfdValue), 0),
|
||||
SyscallSucceedsWithValue(sizeof(kMaxEventfdValue)));
|
||||
|
||||
// Set the eventfd's value to 1.
|
||||
const uint64_t kOne = 1;
|
||||
ASSERT_THAT(write(efd.get(), &kOne, sizeof(kOne)),
|
||||
SyscallSucceedsWithValue(sizeof(kOne)));
|
||||
|
||||
// Set up signal handler.
|
||||
struct sigaction sa = {};
|
||||
sa.sa_sigaction = SigUsr1Handler;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
const auto cleanup_sigact =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(ScopedSigaction(SIGUSR1, sa));
|
||||
|
||||
// Send SIGUSR1 to this thread in 1 second.
|
||||
struct sigevent sev = {};
|
||||
sev.sigev_notify = SIGEV_THREAD_ID;
|
||||
sev.sigev_signo = SIGUSR1;
|
||||
sev.sigev_notify_thread_id = gettid();
|
||||
auto timer = ASSERT_NO_ERRNO_AND_VALUE(TimerCreate(CLOCK_MONOTONIC, sev));
|
||||
struct itimerspec its = {};
|
||||
its.it_value = absl::ToTimespec(absl::Seconds(1));
|
||||
DisableSave ds; // Asserting an EINTR.
|
||||
ASSERT_NO_ERRNO(timer.Set(0, its));
|
||||
|
||||
// Sendfile from tempfd to the eventfd. Since the eventfd is not already at
|
||||
// its maximum value, the eventfd is "ready for writing"; however, since the
|
||||
// eventfd's existing value plus the new value would exceed the maximum, the
|
||||
// write should internally fail with EWOULDBLOCK. In this case, sendfile()
|
||||
// should block instead of spinning, and eventually be interrupted by our
|
||||
// timer. See b/172075629.
|
||||
EXPECT_THAT(
|
||||
sendfile(efd.get(), tempfd.get(), nullptr, sizeof(kMaxEventfdValue)),
|
||||
SyscallFailsWithErrno(EINTR));
|
||||
|
||||
// Signal should have been handled.
|
||||
EXPECT_EQ(signaled, 1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@@ -195,81 +195,6 @@ TEST(SpliceTest, PipeOffsets) {
|
||||
SyscallFailsWithErrno(ESPIPE));
|
||||
}
|
||||
|
||||
// Event FDs may be used with splice without an offset.
|
||||
TEST(SpliceTest, FromEventFD) {
|
||||
// Open the input eventfd with an initial value so that it is readable.
|
||||
constexpr uint64_t kEventFDValue = 1;
|
||||
int efd;
|
||||
ASSERT_THAT(efd = eventfd(kEventFDValue, 0), SyscallSucceeds());
|
||||
const FileDescriptor in_fd(efd);
|
||||
|
||||
// Create a new pipe.
|
||||
int fds[2];
|
||||
ASSERT_THAT(pipe(fds), SyscallSucceeds());
|
||||
const FileDescriptor rfd(fds[0]);
|
||||
const FileDescriptor wfd(fds[1]);
|
||||
|
||||
// Splice 8-byte eventfd value to pipe.
|
||||
constexpr int kEventFDSize = 8;
|
||||
EXPECT_THAT(splice(in_fd.get(), nullptr, wfd.get(), nullptr, kEventFDSize, 0),
|
||||
SyscallSucceedsWithValue(kEventFDSize));
|
||||
|
||||
// Contents should be equal.
|
||||
std::vector<char> rbuf(kEventFDSize);
|
||||
ASSERT_THAT(read(rfd.get(), rbuf.data(), rbuf.size()),
|
||||
SyscallSucceedsWithValue(kEventFDSize));
|
||||
EXPECT_EQ(memcmp(rbuf.data(), &kEventFDValue, rbuf.size()), 0);
|
||||
}
|
||||
|
||||
// Event FDs may not be used with splice with an offset.
|
||||
TEST(SpliceTest, FromEventFDOffset) {
|
||||
int efd;
|
||||
ASSERT_THAT(efd = eventfd(0, 0), SyscallSucceeds());
|
||||
const FileDescriptor in_fd(efd);
|
||||
|
||||
// Create a new pipe.
|
||||
int fds[2];
|
||||
ASSERT_THAT(pipe(fds), SyscallSucceeds());
|
||||
const FileDescriptor rfd(fds[0]);
|
||||
const FileDescriptor wfd(fds[1]);
|
||||
|
||||
// Attempt to splice 8-byte eventfd value to pipe with offset.
|
||||
//
|
||||
// This is not allowed because eventfd doesn't support pread.
|
||||
constexpr int kEventFDSize = 8;
|
||||
loff_t in_off = 0;
|
||||
EXPECT_THAT(splice(in_fd.get(), &in_off, wfd.get(), nullptr, kEventFDSize, 0),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
// Event FDs may not be used with splice with an offset.
|
||||
TEST(SpliceTest, ToEventFDOffset) {
|
||||
// Create a new pipe.
|
||||
int fds[2];
|
||||
ASSERT_THAT(pipe(fds), SyscallSucceeds());
|
||||
const FileDescriptor rfd(fds[0]);
|
||||
const FileDescriptor wfd(fds[1]);
|
||||
|
||||
// Fill with a value.
|
||||
constexpr int kEventFDSize = 8;
|
||||
std::vector<char> buf(kEventFDSize);
|
||||
buf[0] = 1;
|
||||
ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()),
|
||||
SyscallSucceedsWithValue(kEventFDSize));
|
||||
|
||||
int efd;
|
||||
ASSERT_THAT(efd = eventfd(0, 0), SyscallSucceeds());
|
||||
const FileDescriptor out_fd(efd);
|
||||
|
||||
// Attempt to splice 8-byte eventfd value to pipe with offset.
|
||||
//
|
||||
// This is not allowed because eventfd doesn't support pwrite.
|
||||
loff_t out_off = 0;
|
||||
EXPECT_THAT(
|
||||
splice(rfd.get(), nullptr, out_fd.get(), &out_off, kEventFDSize, 0),
|
||||
SyscallFailsWithErrno(EINVAL));
|
||||
}
|
||||
|
||||
TEST(SpliceTest, ToPipe) {
|
||||
// Open the input file.
|
||||
const TempPath in_file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
|
||||
@@ -852,34 +777,6 @@ TEST(SpliceTest, FromPipeMaxFileSize) {
|
||||
EXPECT_EQ(memcmp(rbuf.data(), buf.data(), buf.size()), 0);
|
||||
}
|
||||
|
||||
TEST(SpliceTest, FromPipeToDevZero) {
|
||||
// Create a new pipe.
|
||||
int fds[2];
|
||||
ASSERT_THAT(pipe(fds), SyscallSucceeds());
|
||||
const FileDescriptor rfd(fds[0]);
|
||||
FileDescriptor wfd(fds[1]);
|
||||
|
||||
// Fill with some random data.
|
||||
std::vector<char> buf(kPageSize);
|
||||
RandomizeBuffer(buf.data(), buf.size());
|
||||
ASSERT_THAT(write(wfd.get(), buf.data(), buf.size()),
|
||||
SyscallSucceedsWithValue(kPageSize));
|
||||
|
||||
const FileDescriptor zero =
|
||||
ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_WRONLY));
|
||||
|
||||
// Close the write end to prevent blocking below.
|
||||
wfd.reset();
|
||||
|
||||
// Splice to /dev/zero. The first call should empty the pipe, and the return
|
||||
// value should not exceed the number of bytes available for reading.
|
||||
EXPECT_THAT(
|
||||
splice(rfd.get(), nullptr, zero.get(), nullptr, kPageSize + 123, 0),
|
||||
SyscallSucceedsWithValue(kPageSize));
|
||||
EXPECT_THAT(splice(rfd.get(), nullptr, zero.get(), nullptr, 1, 0),
|
||||
SyscallSucceedsWithValue(0));
|
||||
}
|
||||
|
||||
static volatile int signaled = 0;
|
||||
void SigUsr1Handler(int sig, siginfo_t* info, void* context) { signaled = 1; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user