From b9f468240f9ac86872036e69244c3548cef91337 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Mon, 13 Apr 2026 03:52:53 +0200 Subject: [PATCH] tstest/integration: use hard links for binary copies to avoid /tmp exhaustion When running many parallel integration tests, each subtest copies ~70MB of binaries (tailscale + tailscaled) to its temp directory. With 24+ parallel subtests, this quickly exhausts /tmp space, causing "no space left on device" errors that appear as test flakes. Try hard linking first before falling back to copying. Hard links share the same inode and don't consume additional disk space. Change-Id: I8cddd993af40f99a34f9e994b2f5a6f5daf294bf Co-Authored-By: Claude Opus 4.6 Signed-off-by: Avery Pennarun --- tstest/integration/integration.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tstest/integration/integration.go b/tstest/integration/integration.go index 75af9ca05..99dcecbde 100644 --- a/tstest/integration/integration.go +++ b/tstest/integration/integration.go @@ -93,13 +93,14 @@ func (b BinaryInfo) CopyTo(dir string) (BinaryInfo, error) { ret.Path = filepath.Join(dir, path.Base(b.Path)) switch runtime.GOOS { - case "linux": - // TODO(bradfitz): be fancy and use linkat with AT_EMPTY_PATH to avoid - // copying? I couldn't get it to work, though. - // For now, just do the same thing as every other Unix and copy - // the binary. - fallthrough - case "darwin", "freebsd", "openbsd", "netbsd": + case "linux", "darwin", "freebsd", "openbsd", "netbsd": + // Try hard link first to save disk space. Hard links share the same + // inode so they don't consume additional disk space, which is + // important when running many parallel integration tests. + if err := os.Link(b.Path, ret.Path); err == nil { + return ret, nil + } + // Fall back to copying if hard link fails (e.g., cross-device). f, err := os.OpenFile(ret.Path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o755) if err != nil { return BinaryInfo{}, err