Skip to content
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

Support for OpenBSD #688

Merged
merged 5 commits into from
Aug 9, 2017
Merged

Support for OpenBSD #688

merged 5 commits into from
Aug 9, 2017

Conversation

wezm
Copy link
Contributor

@wezm wezm commented Jul 18, 2017

Fixes #685

These changes get nix building on OpenBSD 6.1. There is one failing test that I want a little guidance on:

error[E0308]: mismatched types
   --> src/sys/event.rs:333:30
    |
333 |     assert!(expected.data == actual.data());
    |                              ^^^^^^^^^^^^^ expected i64, found isize

KEvent::data is:

    pub fn data(&self) -> intptr_t {
        self.kevent.data as intptr_t
    }

I assume the test should be updated to cast to the expected type but wanted to confirm that before making the change.

src/sys/event.rs Outdated
pub type type_of_event_flag = u32;
libc_bitflags!{
pub flags EventFlag: type_of_event_flag {
EV_ADD,
EV_CLEAR,
EV_DELETE,
EV_DISABLE,
#[cfg(not(target_os = "openbsd"))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer to whitelist versus blacklist, this appears to be on mac, ios, dragonly, freebsd and netbsd.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, OpenBSD does have it, see rust-lang/libc#613.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the looks of it they aren't in a released version of OpenBSD yet. The author of that patch added it to the current branch but there hasn't been a release since. I think the linked PR is still unmerged as a result.

I think the right thing to do for now is to leave it out. I can raise another issue to add it when the next OpenBSD release occurs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. But please change this to a whitelist anyways. And add a TODO here that talks about adding it once OpenBSD is released (and name a specific version number so we don't need to look back in time to figure out this comment).

@@ -490,11 +490,13 @@ pub enum SigevNotify {

/// Used to request asynchronous notification of the completion of certain
/// events, such as POSIX AIO and timers.
#[cfg(not(target_os = "openbsd"))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this because libc doesn't support this on openbsd or is it because it's unsupported on OpenBSD?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell it's not supported at all. No mention of sigevent in the man pages or headers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nicer than to wrap this in a module and #cfg that module and then a single line importing everything from it instead of having all of these #cfgs.

pub const SO_TIMESTAMP: c_int = libc::SO_TIMESTAMP;
#[cfg(target_os = "openbsd")]
pub const SO_TIMESTAMP: c_int = 0x0800;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't hardcode values in nix anymore, this needs to be upstreamed into libc before it can be included here.

@Susurrus
Copy link
Contributor

Regarding your specific question, yes it does appear that a cast is missing that'll use as type_of_data.

@wezm
Copy link
Contributor Author

wezm commented Jul 18, 2017

Thanks for the quick review.

Regarding your specific question, yes it does appear that a cast is missing that'll use as type_of_data.

So something like this?

assert!(expected.data as type_of_data == actual.data());

@Susurrus
Copy link
Contributor

I think the other way around. Look at the lines of code around it and it'll be similar.

@asomers
Copy link
Member

asomers commented Jul 19, 2017

@wezm I would say that you should change the output type of the data function to type_of_data.

@wezm wezm changed the title Initial support for OpenBSD Support for OpenBSD Jul 19, 2017
@wezm
Copy link
Contributor Author

wezm commented Jul 19, 2017

@Susurrus @asomers Happy to fix either way. Changing the return type of data would be an API change. Just want to confirm that's ok before going down that route.

Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought I changed my mind. Right now, KEvent has the same interface on all OSes, which is a handy property. Let's do it the way you have it now.

@wezm
Copy link
Contributor Author

wezm commented Jul 20, 2017

Getting closer. All tests (excluding doc tests) are passing except this one:

---- sys::test_socket::test_scm_rights stdout ----
        thread 'sys::test_socket::test_scm_rights' panicked at 'Did not receive passed fd', /usr/obj/ports/rust-1.16.0/rustc-1.16.0-src/src/libcore/option.rs:715

test result: FAILED. 53 passed; 1 failed; 0 ignored; 0 measured

It's going to need bit of digging as the code looks right when compared to the example in CMSG_DATA(3) but there is a fair bit of unsafe work going on in ControlMessage::ScmRights.

src/sys/event.rs Outdated
pub type type_of_event_flag = u32;
libc_bitflags!{
pub flags EventFlag: type_of_event_flag {
EV_ADD,
EV_CLEAR,
EV_DELETE,
EV_DISABLE,
#[cfg(not(target_os = "openbsd"))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. But please change this to a whitelist anyways. And add a TODO here that talks about adding it once OpenBSD is released (and name a specific version number so we don't need to look back in time to figure out this comment).

@@ -490,11 +490,13 @@ pub enum SigevNotify {

/// Used to request asynchronous notification of the completion of certain
/// events, such as POSIX AIO and timers.
#[cfg(not(target_os = "openbsd"))]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nicer than to wrap this in a module and #cfg that module and then a single line importing everything from it instead of having all of these #cfgs.

@@ -242,7 +242,7 @@ fn test_fpathconf_limited() {
#[test]
fn test_pathconf_limited() {
// AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
let path_max = pathconf(".", PathconfVar::PATH_MAX);
let path_max = pathconf("/", PathconfVar::PATH_MAX);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the commit message for that change. It was failing when the tests were run in parallel. Presumably one of them is doing something that makes . No longer exist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. There are indeed some tests that do that.

@@ -242,7 +242,7 @@ fn test_fpathconf_limited() {
#[test]
fn test_pathconf_limited() {
// AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
let path_max = pathconf(".", PathconfVar::PATH_MAX);
let path_max = pathconf("/", PathconfVar::PATH_MAX);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. There are indeed some tests that do that.

@@ -209,6 +209,31 @@ get_int_const(const char* err) {
GET_CONST(ECANCELED);
#endif

#if defined(__OpenBSD__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can revert the changes to this file. This file has been obsolete ever since most constants moved into libc. libc has its own, superior version.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these to get the errno tests passing. It looks like the check_errno macro uses them via assert_const_eq or did I miss something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grr, I thought we had already removed that. Go ahead and leave these changes in for now; we'll delete them in a future PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we do conversions of our code to use upstream libc values, we can remove these tests incrementally until they're all gone. But for now, we should add these tests if we have any hard-coded values (like all the errno values currently are).

@Susurrus Susurrus mentioned this pull request Jul 21, 2017
10 tasks
Copy link
Member

@asomers asomers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two remaining problems with this PR:

  • The hardcoded constant
  • The test_scm_rights failure on FreeBSD. It's repeatable.

@@ -209,6 +209,31 @@ get_int_const(const char* err) {
GET_CONST(ECANCELED);
#endif

#if defined(__OpenBSD__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Grr, I thought we had already removed that. Go ahead and leave these changes in for now; we'll delete them in a future PR.

@wezm
Copy link
Contributor Author

wezm commented Jul 24, 2017

test_scm_rights failure on FreeBSD

Yep I'm working on this at the moment. It's proving quite a challenge to get all OSes working at once. Might take a little bit to get sorted but I am working on it a bit each day.

@wezm
Copy link
Contributor Author

wezm commented Jul 24, 2017

It was an adventure but I think 403cc5e finally resolves the failing control message test (for all platforms). As far as I can tell it was a bug in the implementation that only exposed itself on OpenBSD. More details in the commit message. Next up I'll deal with the other requested changes and get the doc tests passing. Not sure what's up with AlanCI failing to find the commit... but the tests pass on my FreeBSD VM.

@asomers
Copy link
Member

asomers commented Jul 25, 2017

Looks like the OSX build failure is trivial to fix. And don't forget to remove the hardcoded SO_TIMESTAMP value.

bors added a commit to rust-lang/libc that referenced this pull request Jul 31, 2017
Bump to version 0.2.29

Rationale for release: My changes in nix-rust/nix#688 are blocked on getting a libc release out with the missing constant  present.
@wezm
Copy link
Contributor Author

wezm commented Aug 1, 2017

Ok folks, I think all requested changes have been addressed. I've replaced the SO_TIMESTAMP magic number with the one I upstreamed in libc. Should be good to merge now.

@@ -3,7 +3,9 @@

use libc;
use {Errno, Error, Result};
#[cfg(not(target_os = "openbsd"))]
use std::fmt;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be combined into one use statement like use std::fmt::{self, Debug};.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still isn't addressed.

sigevent: libc::sigevent
}
#[cfg(not(target_os = "openbsd"))]
pub mod sigevent {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this module should be public since you glob-import everything into the sys::signal module above.

@Susurrus
Copy link
Contributor

Susurrus commented Aug 1, 2017

You've got a couple of commits in there that I think should be merged with earlier ones as they're fixing problems that were created by this PR. You also have a merge commit there in the middle. I'd prefer if you rebased your changes rather then merged master back into your branch (makes it harder to read the history when there are a ton of merge commits on top of the ones bors adds).

This could also use a CHANGELOG entry if 0.9 didn't work on OpenBSD and the next release will.

I suggest you wait until #647 as it changes a bunch of socket constants.

@wezm
Copy link
Contributor Author

wezm commented Aug 2, 2017

Righto, addressed the comments on src/sys/signal.rs, rebased against current master and added a CHANGELOG entry.


#[cfg(not(target_os = "linux"))]
pub type type_of_msg_iovlen = c_uint;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should only be one empty line following this.

@@ -33,9 +41,9 @@ pub struct msghdr<'a> {
pub msg_name: *const c_void,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct should be replaced with the FFI types declared in libc, but that doesn't need to be done for this PR. Please add a FIXME stating that.

@@ -235,6 +235,7 @@ impl<'a> Iterator for CmsgIterator<'a> {

// Advance our internal pointer.
if cmsg_align(cmsg_len) > buf.len() {
println!("cmsg_align(cmsg_len) > buf.len(): {} > {}", cmsg_align(cmsg_len), buf.len());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this debugging statement should be removed, yes?

CHANGELOG.md Outdated
@@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
([#672](https://github.com/nix-rust/nix/pull/672))
- Added protocol families in `AddressFamily` enum.
([#647](https://github.com/nix-rust/nix/pull/647))
- Added support for OpenBSD.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't "add support". OpenBSD cannot be tested in CI yet, so we haven't added support here, but this PR does do is fix compilation and tests for OpenBSD targets.

@Susurrus
Copy link
Contributor

Susurrus commented Aug 2, 2017

Okay, my previous comments don't make sense if you look at the entire changelog because you have commits that fix issues that you introduce in previous commits. Can you squash 6870ee6 and 9e4e0c0 into one commit? I don't like having commits that introduce changes to have them later refined within the same PR. It makes browsing the git log after the PR is merged more difficult.

@wezm
Copy link
Contributor Author

wezm commented Aug 3, 2017

Thanks for your patience with me on this. I've more aggressively cleaned up and squashed commits to better stand on their own without subsequent changes. I changed the changelog message and added a FIXME to cmsg structs.

Copy link
Contributor

@Susurrus Susurrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is very close to being ready to merge here. Just a few small remaining issues.

@@ -168,7 +168,7 @@ unsafe fn copy_bytes<'a, 'b, T: ?Sized>(src: &T, dst: &'a mut &'b mut [u8]) {
}


use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data};
use self::ffi::{cmsghdr, msghdr, type_of_cmsg_len, type_of_cmsg_data, type_of_msg_iovlen};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you alphabetize this list?

// Private because we don't expose any external functions that operate
// directly on this type; we just use it internally at FFI boundaries.
// Note that in some cases we store pointers in *const fields that the
// kernel will proceed to mutate, so users should be careful about the
// actual mutability of data pointed to by this structure.
//
// FIXME: Replace these structs with the ones defined in libc
// E.g. https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/struct.msghdr.html
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can leave off this link.

src/sys/event.rs Outdated
@@ -79,16 +78,25 @@ pub enum EventFilter {
}

#[cfg(any(target_os = "macos", target_os = "ios",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please alphabetize the order of the OSes since you're already modifying this attribute.

src/sys/event.rs Outdated
#[cfg(any(target_os = "openbsd", target_os = "freebsd",
target_os = "dragonfly", target_os = "macos",
target_os = "ios"))]
#[cfg(any(target_os = "freebsd", target_os = "dragonfly",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please alphabetize the order of the OSes since you're already modifying this attribute.

}

impl SigEvent {
// Note: this constructor does not allow the user to set the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you turn this into a proper doc comment since you're modifying this? This is definitely something that should be exposed to our end users rather than only visible when browsing the source.

@Susurrus
Copy link
Contributor

Susurrus commented Aug 3, 2017

@asomers Can you wrap up your review? I want to make sure all of your concerns are addressed before we merge.

@asomers
Copy link
Member

asomers commented Aug 3, 2017

The CHANGELOG entry is in the ADDED section, but that section should only be for new features. This ia bugfix commit, so its CHANGELOG entry should go into the FIXED section.

wezm added 4 commits August 5, 2017 15:04
There appears to be some interaction with test_pathconf_limited and
another one when they are run in parallel, causing it to return ENOENT
so the path has been changed from . to /.
Also updates cmsg types to match structs on non-Linux OSes.
The implementation of CmsgInterator did not correctly mirror the
way the CMSG_FIRSTHDR and CMSG_NEXTHDR macros work in C. CMSG_FIRSTHDR
does not attempt to align access since the pointer is already aligned
due to being part of the msghdr struct.

CmsgInterator was always aligning access which happened to work on all
platforms except OpenBSD where the use of alignment was adding
unexpected bytes to the expected size and causing the
`cmsg_align(cmsg_len) > self.buf.len()` guard clause to return early.
@wezm
Copy link
Contributor Author

wezm commented Aug 5, 2017

All requested changes have been addressed.

@wezm
Copy link
Contributor Author

wezm commented Aug 8, 2017

Hi folks, could I trouble you for another review. Would love to get this merged.

@asomers
Copy link
Member

asomers commented Aug 8, 2017

All of my concerns are addressed, and I think susuruss's are too. I'll merge in 1 day if @Susurrus has no more objections.

@Susurrus
Copy link
Contributor

Susurrus commented Aug 9, 2017

bors r+

bors bot added a commit that referenced this pull request Aug 9, 2017
688: Support for OpenBSD r=Susurrus

Fixes #685 

These changes get nix building on OpenBSD 6.1. There is one failing test that I want a little guidance on:

```
error[E0308]: mismatched types
   --> src/sys/event.rs:333:30
    |
333 |     assert!(expected.data == actual.data());
    |                              ^^^^^^^^^^^^^ expected i64, found isize
```

`KEvent::data` is:

```
    pub fn data(&self) -> intptr_t {
        self.kevent.data as intptr_t
    }
```

I assume the test should be updated to cast to the expected type but wanted to confirm that before making the change.
@bors
Copy link
Contributor

bors bot commented Aug 9, 2017

@bors bors bot merged commit 0fbd223 into nix-rust:master Aug 9, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants