-
Notifications
You must be signed in to change notification settings - Fork 0
Implement signals, IPC, and networking infrastructure #58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit adds POSIX-style pipe support to Breenix: Kernel infrastructure: - kernel/src/ipc/fd.rs: FdTable with heap-allocated fd array (avoids stack overflow), FdKind enum for StdIo/PipeRead/PipeWrite - kernel/src/ipc/pipe.rs: PipeBuffer with 64KB circular buffer, reader/writer tracking for EOF/broken pipe detection - kernel/src/syscall/pipe.rs: sys_pipe() and sys_close() implementations Syscall integration: - Added Close (6) and Pipe (22) syscall numbers - Updated sys_read/sys_write to route through FdTable for pipe support - Added FdTable to Process struct for per-process file descriptors Userspace support: - libs/libbreenix: Added pipe() and close() wrappers - userspace/tests/pipe_test.rs: End-to-end test for pipe IPC The FdTable uses Box to heap-allocate its 256-entry fd array, preventing stack overflow during process creation (the array is ~6KB). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add pipe_test binary to userspace/tests Cargo.toml and build.sh - Add test_pipe() function in kernel/src/test_exec.rs to load and run the pipe_test binary during boot - Add call to test_pipe() in kernel/src/main.rs test sequence - Add PIPE_TEST_PASSED boot stage marker in xtask/src/main.rs - Update pipe_test.rs to emit boot stage marker The pipe test validates: - pipe() syscall creates valid file descriptors - Writing to pipe write end succeeds - Reading from pipe read end retrieves correct data - close() syscall properly closes pipe file descriptors 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move FdTable from socket/mod.rs to ipc/fd.rs (proper layer) - Change UdpSocket to Arc<Mutex<>> pattern (matches pipes) - Remove without_interrupts from process creation (prevents deadlock) - Simplify copy_to_user (no PROCESS_MANAGER lock needed) - Add per-CPU context switch diagnostic fields All 76 boot stages pass. Build clean with zero warnings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| } | ||
| } | ||
| Err(24) // EMFILE | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Pipe reference counts not updated during dup/clone operations
The dup(), dup2(), and FdTable::clone() implementations clone the Arc<Mutex<PipeBuffer>> but don't increment the readers/writers counts inside PipeBuffer. These counts are used to detect EOF (writers=0) and broken pipe (readers=0). When a pipe fd is duplicated and then the original is closed via sys_close (which calls close_read()/close_write()), the count drops to 0 even though a valid fd still exists. This causes incorrect EPIPE errors on write or premature EOF on read. Additionally, dup2 discards the result of closing new_fd with let _ = ..., which skips the cleanup logic in sys_close that decrements pipe reference counts.
Additional Locations (2)
| log::debug!("sys_close: Closed UDP socket fd={}, unbound port {}", fd, port); | ||
| } else { | ||
| log::debug!("sys_close: Closed unbound UDP socket fd={}", fd); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: UDP socket unbinds prematurely when fd is closed
The sys_close implementation for UDP sockets explicitly calls unbind_udp() when a file descriptor is closed. However, with the new Arc<Mutex<UdpSocket>> design that enables socket sharing via dup/fork, this is incorrect. If two file descriptors reference the same socket and one is closed, the socket gets unbound while the other fd is still valid. The UdpSocket::Drop implementation already handles unbinding when the last reference is released, so the explicit unbind in sys_close should be removed to allow shared sockets to remain bound until all references are closed.
Summary
This PR adds foundational IPC and networking capabilities to Breenix:
Key Changes
Signals (currently disabled due to QEMU 8.2.2 bug)
Pipe IPC
UDP Sockets
Architecture Improvements
Test plan
🤖 Generated with Claude Code
Note
Introduce unified IPC with pipes and close syscalls, refactor per-CPU/TSS stack handling, and update networking, syscalls, userspace wrappers, and tests to use the new FD model.
ipc/module withfd.rs(FdTable,FdKind) consolidating stdio, pipes, and UDP sockets; remove old FD table fromsocket/mod.rs.PipeBuffer(ipc/pipe.rs) andcreate_pipe(). Add syscallssys_pipeandsys_close; wire in dispatcher/handler. Extendsys_read/sys_writeto support pipe ends.libbreenix::io::{pipe, close}; newpipe_testbinary and build integration.ipc::fd::{FdKind, MAX_FDS}and lockUdpSocketviaArc<Mutex<...>>. Adjust socket syscalls to the new FD model.per_cpu::PerCpuData: switchcpu_idandkernel_stack_toptou64, changeexception_cleanup_contexttou8, add switch diagnostics (canaries, TSC, counters), assert new size. Change APIs:kernel_stack_top()/set_kernel_stack_top()/update_tss_rsp0()now useu64.main.rs,interrupts/context_switch.rs,test_userspace.rs) to passas_u64()and set TSS.RSP0 accordingly.PipeandClose; route indispatcher.rsandhandler.rs. Relaxcopy_to_userto avoid manager lock; extend read/write path for pipes and stdio.ipc::FdTableinprocess::Process; adjust creation path to avoid disabling interrupts to prevent deadlocks.pipe_testin userspace Cargo/build script;xtaskadds boot-stage check forPIPE_TEST_PASSED.Written by Cursor Bugbot for commit 97480a3. This will update automatically on new commits. Configure here.