WebAssembly/wasi-filesystem

Drop explicit preopens

Opened this issue · 5 comments

Given WASI's CloudABI heritage I understand why preopens currently are the way that they are.

But they feel like something that should be just an host implementation detail. Ie. could the following also work?:

Remove

get-directories: func() -> list<tuple<descriptor, string>>

in exchange for:

instance-root-directory: func() -> descriptor

which returns a single directory that represents the "default filesystem". In similar vein to:

  • wasi-clocks/instance-monotonic-clock
  • wasi-clocks/instance-wall-clock
  • wasi-network/instance-network

By default this is an empty directory. But the host can "mount" specific external directories/files into it. Exactly how the contents of this "filesystem" are populated (preopened or not), would be of concern only to the host, not the client application / libc.

I'm up for exploring this idea more sometime in the future, but for the preview2 timeframe I have advocated that we keep interfaces and concepts that existed in preview 1 as similar as we can possibly get away with.

I think this is a good idea. This would solve WebAssembly/wasi-libc#414

for the preview2 timeframe I have advocated that we keep interfaces and concepts that existed in preview 1 as similar as we can possibly get away with.

Yeah, that's totally fine!

The main reason why I am asking this is because I'm trying to get a grip on where WASI wants to end up regarding "preopens", so I can take that into account for wasi-sockets.

As the person who initially brought preopens to WASI, based on similar ideas in CloudABI and Capsicum, I agree. I've also come to believe that migrating wasi-filesystem to have a rooted filesystem view would be beneficial to WASI. This would be from many people's perspective a much more "normal" filesystem API. We could have an open function where you can just pass it a string, and open a file. We could even add a builtin current working directory. Overall, this would eliminate a common source of friction when people look to port code to WASI.

This new namespace could still be expected to be sandboxed, but the sandbox could look more like a simple VFS with things mounted in it. Many use cases could just use that directly, rather than using preopens. I expect the VFS could even be populated by the existing --dir command-line flags. Overall, it seems like this is something we can migrate to incrementally, without breaking compatibility with existing code.

Why the change in stance? Preopens were added in the Preview 1 era, at a time when there wasn't even a component model proposal, and we had a lot of questions with no answers. But today:

  • We can be more confident that wasi-filesystem should just be a filesystem API, and specialize it accordingly. WASI will add many new kinds of resources, but not everything is a file, and we now have tools like an IDL, handles and resources, and more, so we don't need wasi-filesystem to be a general-purpose resource namespace.
  • We now have a more developed understanding of "link-time authority". In particular, one of the key properties of capability systems is that all authorities be interposable, and with link-time authority, we can still interpose them. We will still need to watch out for ghosts, strings being passed around that implicitly assume everyone has the same filesystem namespace, but we can help by building up tooling such as WASI-Virt to promote best practices.

(But what if you want an Everything Is A File experience? We can provide it, by teaching WASI-Virt how to implement features in terms of wasi-filesystem APIs!)

So, should we start moving in this direction? I don't see any objections to this overall issue so far, but I'll do some more asking around.

yamt commented

This new namespace could still be expected to be sandboxed, but the sandbox could look more like a simple VFS with things mounted in it.

i concern the "simple VFS" is likely a bit more expensive than preopens, which is just a list.