wasmtime icon indicating copy to clipboard operation
wasmtime copied to clipboard

WasiCtx and preopen

Open donovano opened this issue 4 years ago • 8 comments

Hi,

Wasi::new takes a WasiCtx parameter that can be created with environment args as shown in your examples on WASI and linking. With the wasmtime binary you can pass the --dir parameter to preopen a directory where the wasm module can read a file from. I did not so far get this to work when instantiating a WASI module using your API. It seems the args passed into the WasiCtx creation does not end up with directories being pre-opened. The end result is that file IO from a WASI module does not seem to work unless you are calling it from the wasmtime binary. Maybe I'm missing something? Thanks.

donovano avatar May 27 '20 19:05 donovano

Can you describe how you're setting up the WasiCtx? Are you calling preopened_dir to add the preopens?

sunfishcode avatar May 27 '20 19:05 sunfishcode

Sure, the following is based on some code of wasmtime in run.rs. I suspect the File::open might be not correct but not sure. The wasm module tries to open a file in the current directory of the executable. Anyway...

   ...
   let mut linker = Linker::new(&store);
   let mut cx1 = wasi_common::WasiCtxBuilder::new();
   let mut path = Path::new(".");
   let mut file = match File::open(&path) {
      Err(why) => panic!("couldn't open file: {}",
            why.description()),
      Ok(file) => {println!("could open ."); file},
   };  
   cx1.preopened_dir(file.try_clone()?, ".");
   let cx1 = cx1.build()?;
   let wasi = Wasi::new(&store, cx1);
   //NOTE the following also did not work when passing the --dir=. parameter to the executable
   //let wasi = Wasi::new(&store, WasiCtx::new(std::env::args())?);
   wasi.add_to_linker(&mut linker)?;
   ...

donovano avatar May 27 '20 20:05 donovano

Offhand I don't see anything wrong there. Do you know what string the application code is attempting to open that isn't working?

sunfishcode avatar May 27 '20 22:05 sunfishcode

Here is the simple code section from the wasm module. Note that this works when called from wasmtime (with --dir=.). The file is in the current directory:

...
let path = Path::new("somefile.txt");
let mut file = match File::open(path) {
...

I'll fish around for something else that might be causing this if you say that it all looks sound.

donovano avatar May 27 '20 22:05 donovano

Solved the problem. start wasn't being called. Thanks for the help.

donovano avatar May 28 '20 12:05 donovano

I'm having a similar issue @donovano, may I ask which start was not being called?

Thank you!

linouxis9 avatar Jun 06 '20 23:06 linouxis9

Same problem here, any ideas?

alexandruradovici avatar Apr 30 '24 07:04 alexandruradovici

It turns out that using

let (command, _instance) = wasmtime_wasi::bindings::sync::Command::instantiate(
        &mut store,
        &component,
        &mut linker,
    ).unwrap();

to instantiate the component make preopened_dir to work, but using

let example_res = Root::instantiate(&mut store, &component, &linker);
    match example_res {
        Ok((instance, _)) => {
            instance.interface0.call_funcall(&mut store).unwrap();
        }
        Err(e) => println!("Error at calling function {:?}", e),
    }

fails.

We use a reactor component, so I think we are missing some wasi initialization step, we just cannot figure out which one.

alexandruradovici avatar Apr 30 '24 08:04 alexandruradovici