From 3323dab1f45bbad1033cdd0c2fbfb9884c5d54cc Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 15 Dec 2022 17:09:00 -0500 Subject: [PATCH] os/exec: retry ETXTBSY errors in TestFindExecutableVsNoexec I made this test parallel in CL 439196, which exposed it to the fork/exec race condition described in #22315. The ETXTBSY errors from that race should resolve on their own, so we can simply retry the call to get past them. Fixes #56811. Updates #22315. Change-Id: I2c6aa405bf3a1769d69cf08bf661a9e7f86440b4 Reviewed-on: https://go-review.googlesource.com/c/go/+/458016 Reviewed-by: Ian Lance Taylor Run-TryBot: Bryan Mills Auto-Submit: Bryan Mills TryBot-Result: Gopher Robot --- src/os/exec/lp_linux_test.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/os/exec/lp_linux_test.go b/src/os/exec/lp_linux_test.go index 98c3a7b9e0..845573fb14 100644 --- a/src/os/exec/lp_linux_test.go +++ b/src/os/exec/lp_linux_test.go @@ -5,6 +5,7 @@ package exec import ( + "errors" "internal/syscall/unix" "os" "path/filepath" @@ -48,8 +49,20 @@ func TestFindExecutableVsNoexec(t *testing.T) { t.Fatalf("findExecutable: got %v, want nil", err) } - if err := Command(path).Run(); err != nil { - t.Fatalf("exec: got %v, want nil", err) + for { + err = Command(path).Run() + if err == nil { + break + } + if errors.Is(err, syscall.ETXTBSY) { + // A fork+exec in another process may be holding open the FD that we used + // to write the executable (see https://go.dev/issue/22315). + // Since the descriptor should have CLOEXEC set, the problem should resolve + // as soon as the forked child reaches its exec call. + // Keep retrying until that happens. + } else { + t.Fatalf("exec: got %v, want nil", err) + } } // Remount with noexec flag. -- 2.48.1