]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: retry ETXTBSY errors in TestFindExecutableVsNoexec
authorBryan C. Mills <bcmills@google.com>
Thu, 15 Dec 2022 22:09:00 +0000 (17:09 -0500)
committerGopher Robot <gobot@golang.org>
Fri, 16 Dec 2022 03:04:44 +0000 (03:04 +0000)
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 <iant@google.com>
Run-TryBot: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/os/exec/lp_linux_test.go

index 98c3a7b9e0bb85262257ac297556fa516ad0ad92..845573fb14a4d2dca972740dfffc32e2a61beaca 100644 (file)
@@ -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.