-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Port to OpenBSD! #2980
Port to OpenBSD! #2980
Conversation
I'll also note that this depends on darfink/region-rs#8, which was recently added but has not yet been released yet; I'll ping over there to see if they can release a new version to crates.io. |
Subscribe to Label Actioncc @kubkon
This issue or pull request has been labeled: "wasi"
Thus the following users have been cc'd because of the following labels:
To subscribe or unsubscribe from this label, edit the |
@cfallin, I'm interested in why the openvino-sys crate is failing: the way we build it here, it should have no target-specific logic since it uses |
It's an issue with some platform-specific constants that are defined with
|
system-interface 0.6.6 and posish 0.6.3 are now available. |
// This is the kernel-entry register-save frame format and is | ||
// *unlikely* to change across OpenBSD versions, but note that | ||
// OpenBSD makes no guarantee of ABI compatibility across any | ||
// release. |
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.
I'd suggest submitting a PR to the libc crate for this. The netbsd version of this is straightforward, so hopefully openbsd's is too.
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.
Sure thing -- created rust-lang/libc#2242. It might be a bit until this is easily usable without building rustc from source (the platform doesn't have rustup so it would likely be available with the packages in the next OpenBSD release in October) but then this PR isn't in any hurry either :-)
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.
So it looks like there was an ongoing PR for this (rust-lang/libc#2189) that is somewhat complex, and stalled. For now I added a C helper and I'm happy to revisit this when Rust support exists, if that seems reasonable to you! (Also I misspoke above w.r.t. waiting for an OS package update -- libc
is just a crate, of course, not part of the stdlib distro proper.)
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.
The C wrapper looks fine to me. I suggest adding a link to rust-lang/libc#2189 in a comment so that people looking to refactor that code can easily check on its status.
@sunfishcode I've updated this now with some spare cycles and I think it might be good for another look, whenever you have the chance! It's still pending a region.rs release but I've pinged over there. I resolved the There's also some version weirdness where cap-std-* is pulling in two versions of |
Updated, thanks! This just depends now on (i) a region-rs release, and (ii) resolution of some multi-crate-version weirdness: @sunfishcode, it seems that we have:
in general it seems the various cap-std-related crates have inconsistent dependencies on |
@alexcrichton PTAL again (with low priority for this unofficial side-project!) re: fibers -- there's some additional flags-setting needed that I hadn't realized before too, as OpenBSD has a special mitigation that requires blessing stack memory in a certain way. |
// On OpenBSD, we need to use MAP_STACK to specify that a page can contain a | ||
// stack; otherwise, we will get a SIGSEGV when it is used as such. | ||
// | ||
// Note also that MAP_STACK must be specified with PROT_READ|PROT_WRITE, and | ||
// Note that MAP_STACK must be specified with PROT_READ|PROT_WRITE, and |
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.
MAP_STACK
can also be used on Linux. It is currently a no-op, but according to the man page it is accepted such that if a future architecture requires special handling for the stack, no program changes are necessary.
With latest updates, all tests pass in On a slightly less-unofficial note, at some point it would be neat to articulate a tier strategy for platform support; I imagine something like Rust's tier 1/2/3 (tested, compiled, and best-effort respectively?), where OpenBSD is definitely tier 3, but there might be some systems we could include at tier 2 (other BSDs? Linux/musl? macOS/aarch64?) if cross-compilation works. |
instance_limits: &InstanceLimits, | ||
tunables: &Tunables, | ||
) -> Result<Self> { | ||
panic!("Pooling allocator not supported on OpenBSD due to limits in stack mmap'ing."); |
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.
What kind of limits?
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.
MAP_STACK and issues with the way that the pooling allocator deallocs/reallocs to zero; see the commit message on the commit that added this line.
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.
To give a little more detail: this check in the OpenBSD kernel's mmap() disallows requesting a fixed address for a MAP_STACK mmap, so one can't use this to get fresh CoW pages in an existing stack area.
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.
Personally I don't mind tier 2 ish platforms so long as they don't impose a maintenance burden, but I personally find it somewhat burdensome to try to deal with #[cfg]
in lots of places. I'm a bit worried about the size of directives added to tests and such. Without any CI this is inevitable to regress over time, and I'm not sure if it's really too worthwhile to get the test suite "green" within a snapshot in time, only to have it not green later.
} | ||
|
||
/// Maps a new stack with a guard page. Returns (top, len). | ||
#[cfg(target_os = "openbsd")] |
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.
Since mmap
is roughly the same could this use if cfg!(...)
instead of #[cfg]
so we get some type-checking when compiling for other unix platforms? (not changing the functionality here of course, just the structure)
@@ -344,6 +349,15 @@ impl InstancePool { | |||
Ok(pool) | |||
} | |||
|
|||
#[cfg(target_os = "openbsd")] |
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.
Similar to above could this be an if cfg!
at the top of the function which panics? (I like to keep #[cfg]
to a minimum if we can since we can't type-check anything that's excluded)
libc::PROT_READ | libc::PROT_WRITE, | ||
); | ||
assert_eq!(r, 0, "mprotect to configure memory for sigaltstack failed"); | ||
#[cfg(not(target_os = "openbsd"))] |
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.
Could this use an if
instead of a conditional compilation to guard this?
@@ -33,6 +33,7 @@ fn initializes_linear_memory() -> Result<()> { | |||
} | |||
|
|||
#[test] | |||
#[cfg(not(target_os = "openbsd"))] |
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.
Could this test be changed to use skip_pooling_allocator_tests
instead of adding a cfg here?
@@ -447,6 +448,7 @@ fn async_with_pooling_stacks() { | |||
} | |||
|
|||
#[test] | |||
#[cfg(not(target_os = "openbsd"))] |
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.
Could this (and the above test) use skip_pooling_allocator_tests
instead?
@@ -220,6 +220,7 @@ fn test_initial_table_limits_exceeded() -> Result<()> { | |||
} | |||
|
|||
#[test] | |||
#[cfg(not(target_os = "openbsd"))] |
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.
Can this use skip_pooling_allocator_tests
?
@@ -539,6 +547,7 @@ fn parse_dwarf_info() -> Result<()> { | |||
|
|||
#[test] | |||
#[cfg_attr(all(target_os = "macos", target_arch = "aarch64"), ignore)] // TODO #2808 system libunwind is broken on aarch64 | |||
#[cfg_attr(target_os = "openbsd", ignore)] // backtraces are broken on OpenBSD |
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.
Could this perhaps be extracted to a helper function in this module that tests for arm64 macos and openbsd and skips the tests if that's true?
@cfallin #3049 updates almost everything to rustc_version 0.4.0, except wasmtime still depends on criterion which depends on cast which depends on rustc_version 0.3.3. I've now submitted japaric/cast.rs#34 to update cast. |
Verified to work with several simple Wasm modules on an OpenBSD 6.9 x86_64 machine, built with the Rust included in the packages collection (`pkg_add rust`) because `rustup` doesn't support OpenBSD. This depends on a not-yet-released version of region-rs; this commit will be updated once a new release is made.
OpenBSD >= 6.4 requires a special `MAP_STACK` flag to `mmap()` when allocating any memory that will be used as a stack. This mapping attribute is checked whenever the kernel returns to userspace, according to the stack pointer's current value. If SP points to other memory, the process will receive SIGSEGV.
Also disable the pooling allocator and associated tests on OpenBSD; its method of zeroing the stack (unmapping and remapping at the same fixed address) is not compatible with MAP_STACK, which forbids fixed mapping requests.
I just rebased onto latest Unfortunately it looks like new build failures have cropped up in the meantime, this time in Given the moving target, the fact that we probably won't have a reasonable way to test this on CI, and the fact that we (or at least I) don't really have the time to support another platform beyond "one weekend morning once every few months" (this PR so far), I think I'll go ahead and close this PR. We should definitely reconsider this if/when OpenBSD graduates from tier3 and Rustup adds binaries, and if/when we have a way of adding native GitHub CI runners, at which point someone could run OpenBSD CI. Until then I'll keep the |
Verified to work with several simple Wasm modules on an OpenBSD 6.9
x86_64 machine, built with the Rust 1.51.0 included in the packages
collection (
pkg_add rust
) becauserustup
doesn't supportOpenBSD.
This requires a number of PRs to upstream crates to be merged and
released on crates.io first; as a temporary measure, this commit
includes a number of patches in the toplevel
Cargo.toml
to referto git branches. Once those patches are merged and released,
I can update this PR (cc @sunfishcode).
The only change to wasmtime code itself is in the trap-handler runtime.
I had to hardcode the offset to RIP in the signal frame, because
libc
doesn't have a struct definition for OpenBSD. If we think it would be better
to get that upstreamed, I can do that instead. Or, we could go back to a
C helper and just include
<sys/signal.h>
, but I suspect we don't want to do that.This also disables
wasi-nn
by default, because theopenvino-sys
crate fails to build on OpenBSD. Ideally we would either fix
upstream or include some more build configuration to exclude the
feature on our end on OpenBSD; unfortunately it seems (according
to rust-lang/cargo#1197) that target-specific features are not
yet supported by Cargo, so this is not very easy to do. I'd be interested
in @abrown's thoughts on this!
Also note that we won't be able to build or test this platform on CI,
unfortunately, for three reasons: (i)
rustup
doesn't carry toolchain buildsfor OpenBSD, I think because of the OS's "no ABI compatibility across releases"
policy; (ii) GitHub CI Actions doesn't have any runners
for this platform; and (iii) distributing binaries is difficult, for the above
ABI-compatibility reasons. Nevertheless, it would be nice to be able to say
that it has been known to work at one time, and also maybe at some point
in the distant future someone will see fit to include us in the OpenBSD
ports/packages tree.
Low priority for review (this was just a fun side-adventure). Thanks!