Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions go/internal/runtime/microvm/launch.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,11 @@ func vmmArgs(cfg BootConfig, consolePath string, opts launchOptions) []string {
return args
}

// startChild sets the child's Pdeathsig (a best-effort orphan guard: on Linux
// PR_SET_PDEATHSIG fires on the spawning THREAD's death, so the spawn holds the
// OS thread for it to bind reliably) and captures its stdout+stderr to logPath
// so a boot failure can surface the daemon's own diagnostics. The real teardown
// startChild installs the child's best-effort orphan guard via the
// platform-specific orphanGuardSysProcAttr (Linux PR_SET_PDEATHSIG, which fires
// on the spawning THREAD's death — so the spawn holds the OS thread for it to
// bind reliably; a no-op elsewhere) and captures its stdout+stderr to logPath so
// a boot failure can surface the daemon's own diagnostics. The real teardown
// guarantee is Shutdown, not Pdeathsig (record §(g) lines 300-303).
func startChild(c *child) error {
logFile, err := os.OpenFile(c.logPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o600)
Expand All @@ -295,7 +296,7 @@ func startChild(c *child) error {
// dup'd it into the child. Close after Start below.
c.cmd.Stdout = logFile
c.cmd.Stderr = logFile
c.cmd.SysProcAttr = &syscall.SysProcAttr{Pdeathsig: syscall.SIGTERM}
c.cmd.SysProcAttr = orphanGuardSysProcAttr()

runtime.LockOSThread()
defer runtime.UnlockOSThread()
Expand Down
16 changes: 16 additions & 0 deletions go/internal/runtime/microvm/orphanguard_noop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//go:build unix && !linux

package microvm

import "syscall"

// orphanGuardSysProcAttr returns nil on non-Linux unix (darwin): there is no
// PR_SET_PDEATHSIG equivalent, so the child gets no parent-death guard. The
// microVM launcher only runs for real on Linux (KVM); this build exists so the
// unix-tagged package cross-compiles on darwin — e.g. when `go build
// ./cmd/compass-app` pulls microvm into a darwin compile — without naming the
// Linux-only Pdeathsig field. Teardown correctness does not depend on the guard
// (Shutdown is the real guarantee, record §(g)).
func orphanGuardSysProcAttr() *syscall.SysProcAttr {
return nil
}
19 changes: 19 additions & 0 deletions go/internal/runtime/microvm/orphanguard_pdeathsig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//go:build linux

package microvm

import "syscall"

// orphanGuardSysProcAttr returns the SysProcAttr that installs the child's
// best-effort orphan guard. On Linux that is PR_SET_PDEATHSIG (SIGTERM): the
// signal fires on the spawning THREAD's death, so startChild holds the OS thread
// across cmd.Start for it to bind reliably. The real teardown guarantee is
// Shutdown, not Pdeathsig (record §(g)); this only shortens the window a wedged
// host leaves a VMM orphaned.
//
// Pdeathsig is a Linux-only field of syscall.SysProcAttr, so naming it directly
// under //go:build unix would fail the darwin compile — this helper is the
// per-platform seam that keeps the unix-tagged launcher portable.
func orphanGuardSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{Pdeathsig: syscall.SIGTERM}
}
Loading