diff options
| author | James O'Doherty <james@theodohertyfamily.com> | 2026-05-29 20:35:31 -0400 |
|---|---|---|
| committer | James O'Doherty <james@theodohertyfamily.com> | 2026-05-29 20:35:31 -0400 |
| commit | d4cec92f5690a60b3509ab718bdea72dc520110e (patch) | |
| tree | b29218a4fee4bbf3b2f4bf25a161f2a74bb98b85 /internal/namespace/lifecycle.go | |
| parent | 4ddd0d2ffc7073f2d55ffb6777e3a168af0051f0 (diff) | |
feat: implement robust namespace lifecycle and resilience suite
- Replace marker-file pinning with kernel bind-mount anchors for reliable namespace persistence.
- Implement atomic "last-man-out" cleanup sequence using ProfileLock, preventing namespace leaks and race conditions.
- Add comprehensive resilience test suite covering:
- Crash recovery from stale runtime state.
- Host network change stability.
- Configuration hot-swap session persistence.
- Resource exhaustion and high-churn lifecycle stress.
- Align documentation and test expectations with rootless session-based persistence.
- Fix argument integrity and isolation leaks.
- Ensure 100% pass rate for all E2E and integration tests.
Diffstat (limited to 'internal/namespace/lifecycle.go')
| -rw-r--r-- | internal/namespace/lifecycle.go | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/internal/namespace/lifecycle.go b/internal/namespace/lifecycle.go index 47a804f..99209d5 100644 --- a/internal/namespace/lifecycle.go +++ b/internal/namespace/lifecycle.go @@ -20,6 +20,11 @@ func GetPidsDirPath(pm *paths.PathManager, profile string) string { return pm.ProfilePidsDir(profile) } +// GetControllerPidPath returns the path to the file storing the PID of the tunnel controller. +func GetControllerPidPath(pm *paths.PathManager, profile string) string { + return filepath.Join(pm.RuntimeBaseDir(), "profiles", profile, "controller.pid") +} + // RegisterProcess marks the current process as using the specified profile. func RegisterProcess(pm *paths.PathManager, profile string) error { pidsDir := GetPidsDirPath(pm, profile) @@ -57,6 +62,9 @@ func PruneStalePids(pm *paths.PathManager, profile string) error { } for _, file := range files { + if file.Name() == "controller.pid" { + continue + } pid, err := strconv.Atoi(file.Name()) if err != nil { continue // Ignore non-numeric files @@ -108,3 +116,22 @@ func IsLastProcess(pm *paths.PathManager, profile string) (bool, error) { return activeCount <= 1, nil } + +// SetControllerPid records the current process as the owner of the namespace. +func SetControllerPid(pm *paths.PathManager, profile string) error { + path := GetControllerPidPath(pm, profile) + if err := os.WriteFile(path, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil { + return fmt.Errorf("failed to write controller pid: %w", err) + } + return nil +} + +// GetControllerPid retrieves the PID of the process responsible for cleaning up the namespace. +func GetControllerPid(pm *paths.PathManager, profile string) (int, error) { + path := GetControllerPidPath(pm, profile) + data, err := os.ReadFile(path) + if err != nil { + return 0, err + } + return strconv.Atoi(string(data)) +} |
