Add brokered timerfd support to ulitebox - #1125
Draft
Will Portnoy (willportnoy) wants to merge 6 commits into
Draft
Add brokered timerfd support to ulitebox#1125Will Portnoy (willportnoy) wants to merge 6 commits into
Will Portnoy (willportnoy) wants to merge 6 commits into
Conversation
Introduce a broker-owned timerfd that delegates timer expiry to the host platform, mirroring the brokered TCP/eventfd model: the dedicated epoll reactor in litebox_broker_platform_linux_userland owns a real Linux timerfd and publishes READ readiness via the notification ring; the broker core exposes a provider-driven TimerfdObject; broker_local gains a create/set/get/read client; and the wire protocol carries the new Timerfd request/response family. Details: - protocol: TimerfdSpec + Create/Set/Get/Read messages and wire codec; BrokerOperation::Timerfd / BrokerResult::Timerfd; bump MAX_ENCODED_ACTIVE_MESSAGE_SIZE 38->54 (timerfd set is the new largest active message, still within the 112-byte control-ring slot). - core: TimerfdProvider/PlatformTimerfd traits, TimerfdObject bounded by max_references, ObjectEntry::Timerfd, UnsupportedTimerfdProvider default plus a with_timerfd_provider builder to avoid a BrokerCore::new ripple. - platform: LinuxTimerfdProvider + reactor owning host timerfd fds in an edge-triggered epoll set; readiness snapshot updated on expiry/drain. - userland: wire LinuxTimerfdProvider into the broker binary. - host/local: dispatch + client plumbing; exhaustive Timerfd match arms. The userland_broker integration test drives the real broker binary end to end: it arms a 5ms one-shot host timer, observes READ readiness, and drains exactly one expiration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
Add litebox::event::timer::Timer, a local-core timer backed by a broker-owned host timerfd, mirroring EventCounter: new/set_time/get_time/ read plus IOPollable and Drop, with a TimerError enum (non_exhaustive, matching the EventCounterError sibling convention) and the corresponding BrokerObjectError conversions. Extend the BrokerControl trait with create/set/get/read_timerfd and implement them on BrokerLocalControl. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
Add the guest syscall surface so a sandboxed program can use timerfds: timerfd_create/timerfd_settime/timerfd_gettime, plus read/close/epoll routing, wrapping litebox::event::timer::Timer in a TimerfdSubsystem that mirrors the eventfd subsystem. - common_linux: Itimerspec ABI struct, TfdFlags/TfdTimerFlags, the three SyscallRequest variants and their decode arms, and From<TimerError> for Errno (TryOpError<TimerError> converts via the existing generic impl). - shim: TimerfdSubsystem/TimerFile; sys_timerfd_* with itimerspec marshalling (EINVAL on negative guest seconds, EOVERFLOW on host->guest overflow, NULL old_value tolerated); an extra run_on_raw_fd closure and matching arms in do_read (8-byte expiration count), write (EINVAL), do_close, epoll (EpollDescriptor/DescriptorRef), fcntl and ioctl. clockid is restricted to CLOCK_REALTIME/CLOCK_MONOTONIC. New owned-enum variants trip E0004 at every dispatch site by design; each is resolved with an explicit Timerfd arm, no wildcards. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
Drop the fd suffix from the broker-facing timer object so it matches the Event/Socket/Pipe convention (the fd suffix belongs to the shim subsystem, not the broker object). No behavior change. - protocol: timerfd.rs -> timer.rs, wire/timerfd.rs -> wire/timer.rs; TimerfdRequest/Response -> TimerRequest/Response, TimerfdSpec -> TimerSpec, BrokerOperation::Timerfd/BrokerResult::Timerfd -> ::Timer, encode/decode_timerfd_* -> _timer_*. - core: timerfd.rs -> timer.rs; TimerfdProvider/PlatformTimerfd/ TimerfdObject/TimerfdResource/UnsupportedTimerfdProvider -> Timer*; ObjectEntry::Timerfd -> ::Timer; with_timerfd_provider -> with_timer_provider. - local/host/platform/userland: create/set/get/read_timerfd -> *_timer; LinuxTimerfdProvider/LinuxTimerfd -> LinuxTimer*; handle_timerfd_request -> handle_timer_request. - litebox: BrokerControl timer methods and the guest Timer follow suit. The shim keeps TimerfdSubsystem / sys_timerfd_* / TfdFlags and rustix keeps TimerfdClockId/TimerfdFlags, matching how eventfd names its shim subsystem while the broker object is Event. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
Two timerfd read/settime outcomes previously collapsed to EIO now reach the guest with the errno Linux uses. - EINVAL: the shim validates the itimerspec before issuing the broker request, rejecting a tv_nsec outside [0, 1e9) (negative seconds were already rejected). This is where Linux validates, so a bad timerfd_settime now returns EINVAL instead of a host round-trip that surfaced as EIO. Covered by unit tests. - ECANCELED: a CANCEL_ON_SET timer whose backing clock is set discontinuously reports ECANCELED once and disarms. The reactor now detects the host ECANCELED read and carries a cancelled outcome through the timerfd read path (TimerRead + ReadTimerResponse.cancelled -> BrokerControl -> guest Timer), which the guest maps to ECANCELED via a new TimerError::Cancelled. This is kept entirely within timerfd-owned code so the shared broker ErrorCode/BrokerError wire enums are untouched; the guest-visible behavior is read() -> ECANCELED. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
Add tests/timerfd.c, a self-validating guest that exercises the timerfd syscall surface end to end: one-shot and interval timers, gettime, nonblocking and blocking reads, poll and epoll wakeups, dup sharing, CLOEXEC/NONBLOCK flags, an unknown clock, and an out-of-range itimerspec. Its assertions encode native Linux semantics. test_runner_broker_timerfd_with_rewriter runs the same binary twice: once on the native baseline (the gold standard, proving the assertions match real Linux) and once under Litebox with a broker-owned host timer, and asserts the broker released one object per created timer. spawn_test_broker now installs LinuxTimerProvider so broker-backed guests can create timers. This covers the blocking-read and epoll wakeup paths the broker-only integration test does not, and the EINVAL fidelity fix (a tv_nsec >= 1e9 timerfd_settime returns EINVAL under Litebox exactly as it does natively). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ea6a6c0d-6bb9-4eed-b8f6-5059a53e326d
|
🤖 SemverChecks 🤖 Click for details |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Linux timerfd support to the ulitebox broker. Timer expiry is delegated to the host through the broker — a dedicated epoll reactor owns real host timerfds and publishes readiness through the notification ring, mirroring the brokered TCP and eventfd model. The guest gets timerfd_create/timerfd_settime/timerfd_gettime plus read, close, and epoll through a new shim subsystem.