Skip to content

Fuchsia support for std::process via liblaunchpad. #37936

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

Merged
merged 6 commits into from
Dec 2, 2016

Conversation

tedsta
Copy link
Contributor

@tedsta tedsta commented Nov 22, 2016

Now we can launch processes on Fuchsia via the Rust standard library! ... Mostly.

Right now, ~5% of the time, reading the stdout/stderr off the pipes will fail. Some Magenta kernel people think it's probably a bug in Magenta's pipes. I wrote a unit test that demonstrates the issue in C, which I was told will expedite a fix. https://fuchsia-review.googlesource.com/#/c/15628/

Hopefully this can get merged once the issue is fixed :)

@raphlinus

@rust-highfive
Copy link
Contributor

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @aturon (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@aturon
Copy link
Member

aturon commented Nov 22, 2016

cc @brson @alexcrichton, have one of you been looking at Fuchsia-related PRs?

@alexcrichton
Copy link
Member

Yep, I'll take this one unless @brson gets to it first.

@alexcrichton alexcrichton assigned alexcrichton and unassigned aturon Nov 22, 2016
@tedsta
Copy link
Contributor Author

tedsta commented Nov 23, 2016

The linter complained about my fuchsia-specific stuff in Child::wait_with_output in src/libstd/process.rs, so I took it out. Now it panics on Fuchsia due to the bug in Magenta's pipes implementation (libc::read is returning EIO when it should be returning 0 or EOF). Note that the situation isn't any worse than before, because it used to panic at fork() on Fuchsia. Once the issue is fixed on Magenta's end, this should all work.

@alexcrichton
Copy link
Member

Awesome, thanks for the PR! I wonder, how close to Unix (like Linux Unix) is Fuchsia? If it's relatively far off then it may be worthwhile just creating a whole new src/libstd/sys/fuchsia instead of bolting onto the existing Unix. The changes to process.rs at least seem like they warrant a process_fuchsia.rs at least perhaps as they're changing structures and whatnot.

(hnd_type & 0xFFFF) | ((arg & 0xFFFF) << 16)
}

#[link(name="mxio")]
Copy link
Member

Choose a reason for hiding this comment

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

It's ok to nix these #[link] annotations as they get added via the build script above

-> io::Result<(*mut launchpad_t, mx_handle_t)> {
use sys::magenta::*;

macro_rules! tlp {
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps this could be done instead with a small value on the stack that has a destructor?

@tedsta
Copy link
Contributor Author

tedsta commented Nov 23, 2016

I agree there should be a sys/fuchsia (or maybe sys/magenta since the kernel is called magenta?). It gets less unix-like under musl. File descriptors are bolted on to support musl. A lot of the musl stuff, like fork(), is left unchanged. The kernel will see the linux syscall and return an error.

They say eventually there will be fork emulation, but that we don't want to use it for Rust's libstd. So I wonder if we want to be using the musl's pipe stuff when we could just directly use mx_pipe_t (and all the other things we're wrapping in musl).

@raphlinus
Copy link
Contributor

I'll try to dig in to the code soon. Quick comments: +1 to sys/fuchsia. We've been using "fuchsia" as the identifier (for example in the target triple for llvm) so I think it's best to stay consistent with that.

In general, musl (and mxio as an overlay) provide a whole bunch of posix emulation, and that's a good way to get things working, but as a long term trend I think we'd like to migrate to things running directly in terms of lower-level system functionality.

…d refactored out some now-duplicated code into a 'process_common.rs'
@tedsta
Copy link
Contributor Author

tedsta commented Nov 23, 2016

Made some changes to address @alexcrichton's comments. I don't like the getters I had to add to Command to avoid making some fields public, but I can't think of a better way to keep this DRY.

@alexcrichton
Copy link
Member

Oh yeah we definitely prefer to bind to the "true nature" of a platform where possible. For example we don't use file descriptors on Windows but rather use HANDLE, the actual underlying value, instead. I think it'd be fine to bind all primitives to the underlying Fuchsia primitive if they're not file descriptors as well.

Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

Looking good, thanks!

I think I'm convinced though that we may want to start out with src/libstd/sys/fuchsia rather than continue to bolt onto the existing #[cfg(unix)] category. With functionality like exec not existing and file descriptors being a shim it makes me think that we may wish to stick to a separate body of code. I'd imagine that over time if we continue to add to sys/unix that it'll tangle up the existing code quite a bit and not end up sharing much in the long run?

cc @brson, do you have thoughts?

} else {
unsafe {
mx_cvt(mx_handle_close(self.handle))?;
launchpad_destroy(self.launchpad);
Copy link
Member

Choose a reason for hiding this comment

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

If this is a "proper handle" as opposed to a pid, it may be best to do this in a Drop implementation (like Windows) perhaps?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, good idea

mx_cvt(mx_object_get_info(self.handle, MX_INFO_PROCESS,
&mut proc_info as *mut _ as *mut libc::c_void,
mem::size_of::<mx_info_process_t>(), &mut actual,
&mut avail))?;
Copy link
Member

Choose a reason for hiding this comment

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

We can likely remove the Option<ExitStatus> in this Process by deferring destruction until Drop? (similar to Windows)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It took me a while to grok this statement. I'll play around with it and see where I get.

@raphlinus
Copy link
Contributor

Generally looks good to me (I scanned through the code but didn't go through it with a fine-toothed comb). I agree that it would probably be cleaner to separate out the fuchia stuff from the generic Unix mechanisms.

@tedsta
Copy link
Contributor Author

tedsta commented Nov 29, 2016

Alright, I'll make a sys/fuchsia. Would it be alright if I keep the shims for now and replace them in a series of PRs? It's quite a project, and if it were all in one PR it'd be pretty huge!

@brson
Copy link
Contributor

brson commented Nov 29, 2016

This plan sounds good to me!

@alexcrichton
Copy link
Member

@tedsta yeah that's fine by me, let's go ahead and land the process changes with the organization you've got in this PR, and then we can in follow up PRs move everything to sys/fuchsia

…y launchpads and close handles in Drop impls rather than manually
Copy link
Member

@alexcrichton alexcrichton left a comment

Choose a reason for hiding this comment

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

Just a few minor comments, but otherwise looks good to me!

#[cfg(not(target_os="fuchsia"))]
pub fn get_gid(&self) -> Option<gid_t> {
self.gid
}
Copy link
Member

Choose a reason for hiding this comment

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

These are #[cfg]'d out for lints I think, right? In that case could these just be tagged with #[allow(dead_code)]?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. Done.

@@ -164,6 +171,19 @@ pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
}
}

#[cfg(target_os = "fuchsia")]
pub fn mx_cvt<T>(t: T) -> io::Result<T> where T: TryInto<mx_status_t>+Copy {
Copy link
Member

Choose a reason for hiding this comment

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

I think this is only used in the fuchsia process module, right? If so could this be moved into there for now? When we extract to sys/fuchsia we can put in src/fuchsia/mod.rs likely.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right. Done.

&mut job_copy as *mut mx_handle_t))?;
// Create a launchpad
mx_cvt(launchpad_create(job_copy, self.get_argv()[0],
&mut launchpad as *mut *mut launchpad_t))?;
Copy link
Member

Choose a reason for hiding this comment

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

&mut launchpad.0 I think here could avoid the as cast

Copy link
Contributor Author

Choose a reason for hiding this comment

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

launchpad is actually a regular *mut launchpad_t. It get's Copyed as LaunchpadDestructor.0. Should "move" it into the LaunchpadDestructor and s/LaunchpadDestructor/Launchpad instead?

// Duplicate the job handle
let mut job_copy: mx_handle_t = MX_HANDLE_INVALID;
mx_cvt(mx_handle_duplicate(job_handle, MX_RIGHT_SAME_RIGHTS,
&mut job_copy as *mut mx_handle_t))?;
Copy link
Member

Choose a reason for hiding this comment

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

I think the as cast here is fine to elide

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Collaborator

bors commented Dec 1, 2016

📌 Commit e1b752b has been approved by alexcrichton

bors added a commit that referenced this pull request Dec 2, 2016
Fuchsia support for std::process via liblaunchpad.

Now we can launch processes on Fuchsia via the Rust standard library! ... Mostly.

Right now, ~5% of the time, reading the stdout/stderr off the pipes will fail. Some Magenta kernel people think it's probably a bug in Magenta's pipes. I wrote a unit test that demonstrates the issue in C, which I was told will expedite a fix. https://fuchsia-review.googlesource.com/#/c/15628/

Hopefully this can get merged once the issue is fixed :)

@raphlinus
@bors bors merged commit e1b752b into rust-lang:master Dec 2, 2016
@tedsta tedsta deleted the fuchsia_std_process branch January 24, 2017 21:00
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.

8 participants