summaryrefslogtreecommitdiff
path: root/integrationtests/cmd/ioworkload/scenario_pidfd.go
diff options
context:
space:
mode:
Diffstat (limited to 'integrationtests/cmd/ioworkload/scenario_pidfd.go')
-rw-r--r--integrationtests/cmd/ioworkload/scenario_pidfd.go133
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)
- }
-}