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

Exporting dec_ciovec_slice and ciovec_to_host in wasi-common #939

Closed
jeffcharles opened this issue Feb 12, 2020 · 13 comments · Fixed by #1600
Closed

Exporting dec_ciovec_slice and ciovec_to_host in wasi-common #939

jeffcharles opened this issue Feb 12, 2020 · 13 comments · Fixed by #1600

Comments

@jeffcharles
Copy link
Contributor

I have a use-case where I'd like to perform some operations on the data being sent through an fd_write call on the host rather than sending it through to an underlying file descriptor. The existing fd_write call doesn't appear to offer the ability to work with the input data on the host.

What I think I want (and feel free to correct me if it isn't) is something that would convert the scatter gather IO vectors passed into fd_write to a u8 slice. I think combining dec_ciovec_slice and ciovec_to_host and flattening the resulting IO slices should do that. Would there be any interest in either exporting these functions or exporting a function that would use these two functions to return a slice of the data provided as input to fd_write?

@pchickey
Copy link
Contributor

Does #701 help with your use case?

@jeffcharles
Copy link
Contributor Author

Not exactly. I have an unusual use case but at a high level, the idea is to asynchronously stream a transformed version of stdout and stderr over a network call. Virtual files are better than physical files but it's still an unnecessary abstraction for what I intend to implement.

@pchickey
Copy link
Contributor

@kubkon and I are in the middle of a major renovation to wasi-common (starting with https://github.com/kubkon/wiggle, a new code generator that will take care of all marshalling and validation to and from guest memory) that will eliminate dec_ciovec_slice and ciovec_to_host in the library. Instead, new types and methods will take care of the transformation from the scattered iovecs in guest memory into std::io::IoSlice{Mut}.

Therefore, exporting those funcs wouldn't help much for more than a couple of weeks. You could just copy their implementation into whatever code you need, but if the representation of iovecs ever changes, that will be brittle.

So, if possible, I'd try building on top of the VirtualFile trait, and using the IoSlice types as the basis of your transformations. If there's something about using that abstraction that is too costly, we should look into that deeper, but I'd like to hold off on that until 701 and the wiggle renovations land.

@jeffcharles
Copy link
Contributor Author

Sorry, I missed the public VirtualFile trait on my first pass through that PR. I had thought that only an implementation was publicly exposed. I agree, building on top of that trait should do the job nicely.

@jeffcharles
Copy link
Contributor Author

Glad to see #701 has been merged. Unfortunately I can't seem to figure out how to use the new FileContents trait as a destination for stdout or stderr. The stdout and stderr methods on the builder only appear to take Files and not something that implements FileContents. As well, it's not clear to me if there's a way to wire up preopened_virt to provide destinations for stdout and stderr though I do see a guard in the code that they should not among the pre-opens so I'm guessing that won't work.

How do I map stdout and stderr to a custom implementation of FileContents?

@jeffcharles
Copy link
Contributor Author

Is there anything on the roadmap for supporting what I've proposed above? Another option is if we could get access to the pre-opened file descriptors in the WASI context, then we could wrap fd_write with something that passes through but with a different file descriptor (e.g., if we see a write for file descriptor 1, then pass it through to wasi-common as a write to file descriptor 4), but it doesn't look like that's exposed anywhere other than making a series of WASI calls.

@pchickey
Copy link
Contributor

Sorry for the delay. I think @kubkon is currently working on that aspect of the code. I haven't kept up with every change that has landed & is underway over there.

@kubkon
Copy link
Member

kubkon commented Apr 21, 2020

Hi @jeffcharles! I haven't read into your issue here in too much detail, but I think what you might be looking for, I'm just now trying to bake in into wasi-common. See #1561 for details. Oh, and just to sum up and check that I understand correctly, it all boils down for you to be able to attach your own virtualfs handle as stdio, is it? The PR I've mentioned should hopefully bring us a step closer to that at the very least.

@jeffcharles
Copy link
Contributor Author

it all boils down for you to be able to attach your own virtualfs handle as stdio, is it?

Almost, I want to attach our own virtual files to stdout and stderr. Attaching our own virtualfs to stdio would accomplish that. Really I just want some sort of interface that gives us byte arrays or io slices that we can operate on when an fd_write call occurs which the virtual file stuff does except for calls to file descriptors 1 or 2.

@kubkon
Copy link
Member

kubkon commented Apr 25, 2020

@jeffcharles Cool! Let me see what I can conjure up! If I have any questions, is it OK if I ping you now and then? Also, if it's any more convenient for you, we can sync up on BA's zulip chat as well. Let me know what works best!

@kubkon
Copy link
Member

kubkon commented Apr 26, 2020

@pchickey @jeffcharles ok, I've now created a draft PR (#1600) that hopefully addresses your requirements. With this PR, you should now be able to pass in any implementor of the Handle trait as a valid handle to stdio. Lemme know if that fixes it or if I (very likely!) misunderstood what the problem here actually is :-D

@jeffcharles
Copy link
Contributor Author

It looks like that draft PR does. Just to confirm my understanding of how this would work as a consumer, I should be able to define a custom implementation for FileContents and pass that implementation in a call to InMemoryFile::new and then specify that InMemoryFile I get back from that call to stdout and stderr on WasiCtxBuilder which will result in my custom FileContents implementation's pwrite or pwritev's methods being invoked when a WASI fd_write hostcall occurs?

@kubkon
Copy link
Member

kubkon commented Apr 27, 2020

If I read it right, then yeah, that's the basic idea. In fact, in that draft PR, anything that conforms to the Handle trait will do the job, and in this case, specifying your own implementation of FileContents and then injecting that into InMemoryFile which you then add to the context as a relevant stdio handle should do the job:

let virt_stdout = InMemoryFile::new(Box::new(custom_file_contents));
let ctx: WasiCtx = WasiCtxBuilder::new().stdout(virt_stdout).build()?;

While we're here, you'll note that you have to provide an instance that implements the Handle trait which effectively should be an internal trait of wasi-common. In the future, we'd like to make it completely independent of the underlying runtime and WASI implementation. @sunfishcode has drafted out some really good ideas about this, where the dynamic dispatch problem of this type would be handled at a layer one above the WASI implementation. This essentially implies that as a consumer of WASI you won't have to worry about implementing any traits specific to the runtime at hand. I hope I got the basic idea right. @sunfishcode could you confirm/clarify? :-)

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 a pull request may close this issue.

3 participants