logtail/filch: fix filch test panic (#18660)

Updates rotateLocked so that we hold the activeStderrWriteForTest write
lock around the dup2Stderr call, rather than acquiring it only after
dup2 was already compelete.  This ensures no stderrWriteForTest calls
can race with the dup2 syscall. The now unused waitIdleStderrForTest has
been removed.

On macOS, dup2 and write on the same file descriptor are not atomic with
respect to each other, when rotateLocked called dup2Stderr to redirect
the stderr fd to a new file, concurrent goroutines calling
stderrWriteForTest could observe the fd in a transiently invalid state,
resulting in the bad file descripter.

Fixes tailscale/corp#36953

Signed-off-by: James Scott <jim@tailscale.com>
This commit is contained in:
James Scott
2026-02-10 13:24:00 -08:00
committed by GitHub
parent dc1d811d48
commit 6cbfc2f3ba
2 changed files with 14 additions and 27 deletions
-14
View File
@@ -5,7 +5,6 @@ package filch
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
@@ -121,19 +120,7 @@ func setupStderr(t *testing.T) {
tstest.Replace(t, &os.Stderr, pipeW)
}
func skipDarwin(t testing.TB) {
if runtime.GOOS != "darwin" {
return
}
src := must.Get(os.ReadFile("filch.go"))
if fmt.Sprintf("%x", sha256.Sum256(src)) != "a32da5e22034823c19ac7f29960e3646f540d67f85a0028832cab1f1557fc693" {
t.Errorf("filch.go has changed since this test was skipped; please delete this skip")
}
t.Skip("skipping known failing test on darwin; fixed in progress by https://github.com/tailscale/tailscale/pull/18660")
}
func TestConcurrentWriteAndRead(t *testing.T) {
skipDarwin(t)
if replaceStderrSupportedForTest {
setupStderr(t)
}
@@ -296,7 +283,6 @@ func TestMaxLineSize(t *testing.T) {
}
func TestMaxFileSize(t *testing.T) {
skipDarwin(t)
if replaceStderrSupportedForTest {
t.Run("ReplaceStderr:true", func(t *testing.T) { testMaxFileSize(t, true) })
}