diff --git a/packages/envd/internal/port/forward.go b/packages/envd/internal/port/forward.go index eaf8978f7a..f3f945692b 100644 --- a/packages/envd/internal/port/forward.go +++ b/packages/envd/internal/port/forward.go @@ -143,6 +143,7 @@ func (f *Forwarder) startPortForwarding(ctx context.Context, p *PortToForward) { cgroupFD, ok := f.cgroupManager.GetFileDescriptor(cgroups.ProcessTypeSocat) + // socat keeps envd's SCHED_FIFO + Nice=-20 by design. cmd.SysProcAttr = &syscall.SysProcAttr{ Setpgid: true, } diff --git a/packages/envd/internal/services/process/handler/handler.go b/packages/envd/internal/services/process/handler/handler.go index 82e17d2796..bb90ffc220 100644 --- a/packages/envd/internal/services/process/handler/handler.go +++ b/packages/envd/internal/services/process/handler/handler.go @@ -96,13 +96,14 @@ func New( // User command string for logging (without the internal wrapper details). userCmd := strings.Join(append([]string{req.GetProcess().GetCmd()}, req.GetProcess().GetArgs()...), " ") - // Wrap the command in a shell that sets the OOM score and nice value before exec-ing the actual command. - // This eliminates the race window where grandchildren could inherit the parent's protected OOM score (-1000) - // or high CPU priority (nice -20) before the post-start calls had a chance to correct them. - // nice(1) applies a relative adjustment, so we compute the delta from the current (inherited) nice to the target. + // Reset oom_score_adj, drop SCHED_FIFO via chrt, drop the SYS_NICE + // ambient cap, then apply nice. niceDelta := defaultNice - currentNice() - oomWrapperScript := fmt.Sprintf(`echo %d > /proc/$$/oom_score_adj && exec /usr/bin/nice -n %d "${@}"`, defaultOomScore, niceDelta) - wrapperArgs := append([]string{"-c", oomWrapperScript, "--", req.GetProcess().GetCmd()}, req.GetProcess().GetArgs()...) + wrapperScript := fmt.Sprintf( + `echo %d > /proc/$$/oom_score_adj && exec /usr/bin/chrt --other 0 /usr/bin/setpriv --ambient-caps -all -- /usr/bin/nice -n %d "${@}"`, + defaultOomScore, niceDelta, + ) + wrapperArgs := append([]string{"-c", wrapperScript, "--", req.GetProcess().GetCmd()}, req.GetProcess().GetArgs()...) cmd := exec.CommandContext(ctx, "/bin/sh", wrapperArgs...) uid, gid, err := permissions.GetUserIdUints(user)