mirror of
https://github.com/RhapsodiOS/RhapsodiOS.git
synced 2026-11-03 22:01:40 -07:00
[GH-ISSUE #42] kernel: forking past ~517 processes as root panics in ipc_task_init instead of returning EAGAIN #34
Labels
No labels
bug
documentation
enhancement
enhancement
good first issue
help wanted
help wanted
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
github-starred/RhapsodiOS#34
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @raynorpat on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/RhapsodiOS/RhapsodiOS/issues/42
Symptom
On i386, a root process that forks until fork fails panics the kernel instead of getting
EAGAIN:It happens around the 517th process. Root ignores the per-user
RLIMIT_NPROC, so any root program that forks heavily can take the machine down: a runaway shell loop, a busy daemon, a parallel build.Reproduce
The stress suite's supervision self-check (
src/Commands/stress, ffs-perf branch) originally ran itsforkbombcase as root. It forks paused children until fork fails, and that crashed the v2 guest's kernel (kernel-155.0.0-7, master + ffs fixes). The check now drops to uid -2 withRLIMIT_NPROC=64so the dev guest survives. Run unprivileged under a limit, the same code getsfork: EAGAINcleanly.Minimal reproduction as root:
Cause
Two limits disagree:
medium(maxusers 32), somaxproc = 20 + 16 * 32 = 532(src/kernel-7/conf/param.c:81-82).fork1()only refuses with EAGAIN once that limit is reached.SPACE_MAX = TASK_MAX + 5 = 517(src/kernel-7/kern/mach_param.h:78,TASK_MAX512), soipc_space_create()runs out first.ipc_task_init()(src/kernel-7/kern/ipc_tt.c:99-105) panics whenipc_space_create()oripc_port_alloc_kernel()fails, instead of returning an error up throughtask_createtofork.Possible fixes
maxprocto fewer thanTASK_MAXtasks, leaving room for kernel tasks, so fork refuses with EAGAIN before Mach runs out. This is a one-line config orparam.cchange, plus a check ifmaxprocis ever raised by sysctl.ipc_task_init/task_createreturnKERN_RESOURCE_SHORTAGE, and makefork1()unwind and return EAGAIN. That's more work, but it also covers running out of ports (ipc_port_alloc_kernel) and other zones.Option 1 alone stops the panic for the common case. Option 2 is the robust fix.
Related: #40 and #41, also found by the stress suite.
@raynorpat commented on GitHub (Oct 14, 2026):
Fixed with option 2 in
389eb247dand1fba3717a(local on master, not yet pushed): ipc_task_init now returns KERN_RESOURCE_SHORTAGE instead of panicking, task_create unwinds, procdup/cloneproc unwind the half-built proc, and fork1 returns EAGAIN.Verified on the i386 guest (v2 image, 512 MB, kern.maxproc=532). The old kernel (kernel-155.0.0-7, Oct 10) panics with 'panic: ipc_task_init' under a root fork loop. With the rebuilt kernel the same root loop gets 'Cannot fork' and the guest keeps running (still up, ps works, no reboot).