diff options
Diffstat (limited to 'integrationtests/cmd/ioworkload/scenario_pidfd.go')
| -rw-r--r-- | integrationtests/cmd/ioworkload/scenario_pidfd.go | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/integrationtests/cmd/ioworkload/scenario_pidfd.go b/integrationtests/cmd/ioworkload/scenario_pidfd.go deleted file mode 100644 index 2aafced..0000000 --- a/integrationtests/cmd/ioworkload/scenario_pidfd.go +++ /dev/null @@ -1,133 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - "syscall" - "time" -) - -// pidfdGetfdSuccess duplicates an existing file descriptor through pidfd_getfd. -func pidfdGetfdSuccess() error { - dir, cleanup, err := makeTempDir("pidfd-getfd-success") - if err != nil { - return err - } - defer cleanup() - - path := filepath.Join(dir, "pidfd-getfd-source.txt") - fd, err := syscall.Open(path, syscall.O_RDWR|syscall.O_CREAT, 0o644) - if err != nil { - return fmt.Errorf("open source: %w", err) - } - defer syscall.Close(fd) - - pidfd, err := pidfdOpen(os.Getpid(), 0) - if err != nil { - return fmt.Errorf("pidfd_open self: %w", err) - } - defer syscall.Close(pidfd) - - dupFd, err := pidfdGetfd(pidfd, fd, 0) - if err != nil { - return fmt.Errorf("pidfd_getfd: %w", err) - } - - if _, err := syscall.Write(dupFd, []byte("via pidfd_getfd")); err != nil { - syscall.Close(dupFd) - return fmt.Errorf("write dup fd: %w", err) - } - - // Keep the duplicated fd alive briefly so eventloop can resolve /proc fd path. - time.Sleep(500 * time.Millisecond) - if err := syscall.Close(dupFd); err != nil { - return fmt.Errorf("close dup fd: %w", err) - } - return nil -} - -// pidfdGetfdFailure performs a guaranteed-failing pidfd_getfd call while -// also probing a cross-process call that may fail under ptrace/Yama policy. -func pidfdGetfdFailure() error { - pidfd, err := pidfdOpen(os.Getpid(), 0) - if err != nil { - return fmt.Errorf("pidfd_open self: %w", err) - } - defer syscall.Close(pidfd) - - // Best-effort probe. Depending on kernel ptrace/Yama policy, this may fail - // with EPERM/EACCES; if it succeeds we close the returned fd and continue. - if initPidfd, err := pidfdOpen(1, 0); err == nil { - func() { - defer syscall.Close(initPidfd) - if probeFd, err := pidfdGetfd(initPidfd, 1, 0); err == nil { - syscall.Close(probeFd) - } - }() - } - - _, err = pidfdGetfd(pidfd, 99999, 0) - if err == nil { - return fmt.Errorf("expected pidfd_getfd with invalid source fd to fail") - } - return nil -} - -func pidfdOpen(pid int, flags uintptr) (int, error) { - syscallNr, err := pidfdOpenSyscallNr() - if err != nil { - return 0, err - } - fd, _, errno := syscall.Syscall(syscallNr, uintptr(pid), flags, 0) - if errno != 0 { - return 0, errno - } - return int(fd), nil -} - -func pidfdGetfd(pidfd int, targetFd int, flags uintptr) (int, error) { - syscallNr, err := pidfdGetfdSyscallNr() - if err != nil { - return 0, err - } - fd, _, errno := syscall.Syscall( - syscallNr, - uintptr(pidfd), - uintptr(targetFd), - flags, - ) - if errno != 0 { - return 0, errno - } - return int(fd), nil -} - -func pidfdOpenSyscallNr() (uintptr, error) { - return pidfdOpenSyscallNrForArch(runtime.GOARCH) -} - -func pidfdGetfdSyscallNr() (uintptr, error) { - return pidfdGetfdSyscallNrForArch(runtime.GOARCH) -} - -func pidfdOpenSyscallNrForArch(arch string) (uintptr, error) { - // Go's syscall package does not expose pidfd constants on all toolchains. - switch arch { - case "amd64", "arm64": - return 434, nil - default: - return 0, fmt.Errorf("pidfd_open syscall number not defined for GOARCH=%s", arch) - } -} - -func pidfdGetfdSyscallNrForArch(arch string) (uintptr, error) { - // Go's syscall package does not expose pidfd constants on all toolchains. - switch arch { - case "amd64", "arm64": - return 438, nil - default: - return 0, fmt.Errorf("pidfd_getfd syscall number not defined for GOARCH=%s", arch) - } -} |
