diff options
Diffstat (limited to 'integrationtests/cmd')
| -rw-r--r-- | integrationtests/cmd/ioworkload/scenarios.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/integrationtests/cmd/ioworkload/scenarios.go b/integrationtests/cmd/ioworkload/scenarios.go index dd8d46e..4275fb6 100644 --- a/integrationtests/cmd/ioworkload/scenarios.go +++ b/integrationtests/cmd/ioworkload/scenarios.go @@ -42,6 +42,8 @@ var scenarios = map[string]func() error{ "fcntl-dupfd": fcntlDupfd, "fcntl-setfl": fcntlSetfl, "fcntl-dupfd-cloexec": fcntlDupfdCloexec, + "fcntl-invalid-fd": fcntlInvalidFd, + "fcntl-dupfd-max": fcntlDupfdMax, "rename-basic": renameBasic, "rename-renameat": renameRenameat, "rename-renameat2": renameRenameat2, @@ -789,6 +791,42 @@ func fcntlDupfdCloexec() error { return nil } +// fcntlInvalidFd calls fcntl F_GETFL on an invalid fd (99999). +// The syscall fails with EBADF, but ior should capture the enter_fcntl +// tracepoint because it is recorded on syscall entry. +func fcntlInvalidFd() error { + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, 99999, syscall.F_GETFL, 0) + if errno == 0 { + return fmt.Errorf("expected fcntl on invalid fd to fail") + } + return nil +} + +// fcntlDupfdMax opens a file and calls fcntl F_DUPFD with a minfd value +// that exceeds the process RLIMIT_NOFILE. The kernel rejects this with +// EINVAL, but ior should capture the enter_fcntl tracepoint. +func fcntlDupfdMax() error { + dir, cleanup, err := makeTempDir("fcntl-dupfd-max") + if err != nil { + return err + } + defer cleanup() + + path := filepath.Join(dir, "fcntldupfdmaxfile.txt") + fd, err := syscall.Open(path, syscall.O_RDWR|syscall.O_CREAT, 0o644) + if err != nil { + return fmt.Errorf("open: %w", err) + } + defer syscall.Close(fd) + + // Use a minfd far beyond any realistic RLIMIT_NOFILE. + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD, 1<<30) + if errno == 0 { + return fmt.Errorf("expected fcntl F_DUPFD with extreme minfd to fail") + } + return nil +} + // renameBasic creates a file and renames it via rename(2). // Uses raw SYS_RENAME because Go's syscall.Rename wraps renameat on amd64. func renameBasic() error { |
