macos: add signal shim for downstream rust-vmm crates#268
Conversation
|
This is something similar to #266, same comments apply here... |
|
ah damn you're right and I also saw his pull request on the virtiofsd gitlab repo but I never saw the PR here. So, what I get from this, is that eventfs is already covered by EventNotifier from PR 244 and epoll you're wanting to replace it with mio? If you think this is the direction you'll go, i'll move the PR in that direction, but I see that the mio PR 316 is still open and not merged but I realise it's gotten a lot of action recently, so I guess this is the way to go? |
Adds macOS compatibility for the `signal` module so downstream rust-vmm crates (`vhost`, `vhost-user-backend`, `virtiofsd`, …) can build and run on macOS without code changes. All macOS code is gated behind `#[cfg(target_os = "macos")]` and adds no new dependencies; Linux and Android builds are unaffected. The crate stays at `BSD-3-Clause` and no third-party code is vendored. Host-signal validation uses `1..=SIGUSR2` because macOS signal numbers do not match Linux's: SIGSYS=12, SIGTERM=15, SIGUSR2=31. The `SIGHUP..=SIGSYS` range used on Linux would reject valid macOS signals. Pending-signal clearing goes via unblock-then-reblock because macOS does not expose `sigtimedwait`. What this PR no longer ships, and why: - No `eventfd` shim. The cross-platform `EventConsumer` / `EventNotifier` primitive added in rust-vmm#244 already covers the daemon side of `vhost-user-backend`. The remaining macOS callers of `vmm_sys_util::eventfd::EventFd` are inside the `vhost` crate's `VhostBackend` / `VhostBackendMut` traits, whose only consumers are Linux-only (kernel vhost drivers, vhost-user frontends inside Linux-only VMMs). A small follow-up PR to `vhost` gates those trait methods on Linux, after which nothing in the macOS build path references `vmm_sys_util::eventfd` and a shim is genuinely unnecessary. - No `epoll` shim. Consumers needing epoll-shaped polling on macOS should use `mio` (see vhost #316), which gives proper cross-platform event polling backed by `kqueue` on macOS — a cleaner architectural answer than shimming the Linux API. Tests: - `macos::signal::tests` — validator range, register/block/unblock/kill round-trips, pending-signal clearing. Pre-existing failures in `rand` and `unix::tempdir` on macOS are out of scope for this PR. Signed-off-by: Chris Thomas <chris.thomas@antimatter-studios.com>
The `VhostBackend` and `VhostBackendMut` traits in `vhost/src/backend.rs`
take `&EventFd` in `set_vring_call`, `set_vring_kick`, and
`set_vring_err`. The implementations of these traits are all Linux-only
consumers — kernel vhost drivers (`vhost_kern/`, gated on the
`vhost-kern` feature) and the vhost-user frontend (gated on
`vhost-user-frontend`). No macOS consumer ever calls these methods.
Until now, the unconditional `use vmm_sys_util::eventfd::EventFd;` at
the top of `backend.rs` forced every dependent crate (including
`vhost-user-backend` consumers like virtiofsd) to compile against
`vmm_sys_util::eventfd` even when nothing in the build path called these
methods. On macOS that meant requiring an `eventfd` shim inside
vmm-sys-util just for the type to resolve.
Gate the import, the six trait method signatures, the corresponding
methods in `impl<T: VhostBackendMut> VhostBackend for {RwLock,RefCell}<T>`,
and the test mock + test on `#[cfg(target_os = "linux")]`. The trait
becomes a smaller surface on macOS — exactly the surface that has
working consumers there. Linux behaviour is unchanged.
This unblocks dropping the macOS `eventfd` shim from vmm-sys-util
(rust-vmm/vmm-sys-util#268), and combined with the mio rewrite of
`vhost-user-backend`'s event loop (rust-vmm#316), removes the last hard
dependency between the macOS build path and `vmm_sys_util::eventfd`.
Tested: full virtiofsd → vhost-user-backend → vhost → vmm-sys-util
stack builds and tests pass on aarch64-apple-darwin with no eventfd
shim in vmm-sys-util.
Signed-off-by: Chris Thomas <chris.thomas@antimatter-studios.com>
|
Side note, unrelated to the change, we're moving the vmm-sys-util repository to the mono repo. We're hoping to get this done by the end of the week (2026-05-22). We'll want to merge this in the new repository. Since it's currently not done, I think we can continue the review here, and just move it for the merge there? WDYT? |
|
I updated the pull request to reflect the changes we discussed over the last days. I've tested on my machine using qemu on my macbook and I am happy so far, I don't see any issues with this locally |
Yeah, so we leave this here and I'll rebase it onto the new version when its done. Sounds good |
Don't worry :-)
Right!
Yeah, we should go in that direction IMO. |
How this is related with #263 ? |
|
We finished the merging of vmm-sys-util to rust-vmm, can you please move the PR there? |
Summary
Adds macOS support for the
signalmodule so downstream rust-vmm crates can install process-lifecycle signal handlers (register_signal_handler,block_signal,Killable, etc.) on macOS the same way they do on Linux today. All macOS code is gated behind#[cfg(target_os = "macos")]and adds no new dependencies; Linux and Android builds are unaffected. The crate stays atBSD-3-Clauseand no third-party code is vendored — everything in this PR is original work.Why this is needed
vmm-sys-util already provides a Linux
signalmodule that wraps the POSIXsigaction/sigprocmask/sigpendingmachinery and exposes typed helpers used across the rust-vmm ecosystem. Without an equivalent on macOS, any consumer that uses those helpers fails to compile on macOS — there is novmm_sys_util::signal::*for thecfgresolver to find.Concrete real-world consumer: virtiofsd installs a clean-exit handler for
SIGHUPandSIGTERMso the process tears down its vhost-user socket cleanly when the controlling terminal closes or systemd stops it:The wrapper isn't doing anything magical — it could be written against raw
libc::sigaction— but usingvmm_sys_util::signalhere gets the same validation (validate_signal_num), the same error-handling shape, and the sameKillableabstraction that the rest of the rust-vmm ecosystem uses. Having one consistent API makes consumers portable across platforms with no#[cfg]at the call site.Why this code lives in vmm-sys-util
Symmetric placement: the Linux signal module already lives in vmm-sys-util as
src/linux/signal.rs. Putting the macOS equivalent undersrc/macos/signal.rskeeps "POSIX signal helpers for rust-vmm" in one crate instead of splitting it across crates by platform. Anyone who later wants to bring another rust-vmm crate to macOS gets the same API for free.The shim is also self-contained: ~400 lines, its own unit tests, no new dependencies on the crate. Linux/Android builds don't see it at all.
(If maintainers would prefer to keep vmm-sys-util Linux-only and push macOS shims into the downstream consumers that need them, that's also reasonable and I'm happy to take the code elsewhere. Wanted to flag the option.)
What's in it
src/macos/signal.rs— POSIX signal helpers mirroring the Linux module's public API.1..=SIGUSR2because macOS signal numbers do not match Linux's (SIGSYS=12,SIGTERM=15,SIGUSR2=31). TheSIGHUP..=SIGSYSrange used on Linux would reject valid macOS signals.sigtimedwait.What's not in it (and why)
This PR deliberately omits
eventfdandepollshims that an earlier draft of this branch included, after upstream discussion on #266.No
eventfdshim. The cross-platformEventConsumer/EventNotifierprimitive added in Implement EventNotifier/EventConsumer as a generic event notification #244 already covers the daemon side ofvhost-user-backend. The remaining macOS callers ofvmm_sys_util::eventfd::EventFdare inside thevhostcrate'sVhostBackend/VhostBackendMuttraits, whose only consumers are Linux-only (kernel vhost drivers, vhost-user frontends inside Linux-only VMMs). A small follow-up PR tovhostgates those trait methods on#[cfg(target_os = \"linux\")], after which nothing in the macOS build path referencesvmm_sys_util::eventfdand a shim is genuinely unnecessary.No
epollshim. Consumers needing epoll-shaped polling on macOS should usemio(see Use mio to replace Epoll vhost#316), which gives proper cross-platform event polling backed bykqueueon macOS — a cleaner architectural answer than shimming the Linux API.The previous version of this branch carried both shims, adapted from libkrun, which required dual-licensing the crate as
BSD-3-Clause AND Apache-2.0. Dropping those shims removes the libkrun derivation entirely; the crate stays single-licensedBSD-3-Clause.End-to-end validation
The signal-only version of this PR + rust-vmm/vhost#316 (mio rewrite) + the
VhostBackendcfg-gating follow-up was tested onaarch64-apple-darwin: virtiofsd →vhost-user-backend→vhost→vmm-sys-utilbuilds clean and 75/75 virtiofsd lib tests pass.Tests
macos::signal::tests— validator range, register/block/unblock/kill round-trips, pending-signal clearing.There are 4 pre-existing test failures in
randandunix::tempdiron macOS that this PR does not introduce or fix; they are out of scope.Checklist
CHANGELOG.md.unsafecode is properly documented.