proohit labeled issue #2902:
Test Case
smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txtSteps to Reproduce
Just run the wasm file in the same folder as
test1.txt
.Expected Results
A new file inside
./
with the nametest2.txt
and the same contents astest1.txt
.Actual Results
$ wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt error opening input test1.txt: failed to find a pre-opened file descriptor through which "test1.txt" could be opened
Versions and Environment
Wasmtime version or commit: 0.26.0
Operating system: Ubuntu 20.04
Architecture: x86_64
Extra Info
This is the example for WASI from https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
Here's the code:
use std::fs; use std::io::{Read, Write}; use std::env; fn process(input_fname: &str, output_fname: &str) -> Result<(), String> { let mut input_file = fs::File::open(input_fname) .map_err(|err| format!("error opening input {}: {}", input_fname, err))?; let mut contents = Vec::new(); input_file .read_to_end(&mut contents) .map_err(|err| format!("read error: {}", err))?; let mut output_file = fs::File::create(output_fname) .map_err(|err| format!("error opening output {}: {}", output_fname, err))?; output_file .write_all(&contents) .map_err(|err| format!("write error: {}", err)) } #[no_mangle] pub fn load_model() -> () { let args: Vec<String> = env::args().collect(); let program = args[0].clone(); if args.len() < 3 { eprintln!("usage: {} <input_file> <output_file>", program); return; } if let Err(err) = process(&args[1], &args[2]) { eprintln!("{}", err) } }
And compiled via
cargo build --target=wasm32-wasi --release
proohit opened issue #2902:
Test Case
smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txtSteps to Reproduce
Just run the wasm file in the same folder as
test1.txt
.Expected Results
A new file inside
./
with the nametest2.txt
and the same contents astest1.txt
.Actual Results
$ wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt error opening input test1.txt: failed to find a pre-opened file descriptor through which "test1.txt" could be opened
Versions and Environment
Wasmtime version or commit: 0.26.0
Operating system: Ubuntu 20.04
Architecture: x86_64
Extra Info
This is the example for WASI from https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
Here's the code:
use std::fs; use std::io::{Read, Write}; use std::env; fn process(input_fname: &str, output_fname: &str) -> Result<(), String> { let mut input_file = fs::File::open(input_fname) .map_err(|err| format!("error opening input {}: {}", input_fname, err))?; let mut contents = Vec::new(); input_file .read_to_end(&mut contents) .map_err(|err| format!("read error: {}", err))?; let mut output_file = fs::File::create(output_fname) .map_err(|err| format!("error opening output {}: {}", output_fname, err))?; output_file .write_all(&contents) .map_err(|err| format!("write error: {}", err)) } #[no_mangle] pub fn load_model() -> () { let args: Vec<String> = env::args().collect(); let program = args[0].clone(); if args.len() < 3 { eprintln!("usage: {} <input_file> <output_file>", program); return; } if let Err(err) = process(&args[1], &args[2]) { eprintln!("{}", err) } }
And compiled via
cargo build --target=wasm32-wasi --release
proohit edited issue #2902:
Test Case
smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txtSteps to Reproduce
Just run the wasm file in the same folder as
test1.txt
.
wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt
Expected Results
A new file inside
./
with the nametest2.txt
and the same contents astest1.txt
.Actual Results
$ wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt error opening input test1.txt: failed to find a pre-opened file descriptor through which "test1.txt" could be opened
Versions and Environment
Wasmtime version or commit: 0.26.0
Operating system: Ubuntu 20.04
Architecture: x86_64
Extra Info
This is the example for WASI from https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
Here's the code:
use std::fs; use std::io::{Read, Write}; use std::env; fn process(input_fname: &str, output_fname: &str) -> Result<(), String> { let mut input_file = fs::File::open(input_fname) .map_err(|err| format!("error opening input {}: {}", input_fname, err))?; let mut contents = Vec::new(); input_file .read_to_end(&mut contents) .map_err(|err| format!("read error: {}", err))?; let mut output_file = fs::File::create(output_fname) .map_err(|err| format!("error opening output {}: {}", output_fname, err))?; output_file .write_all(&contents) .map_err(|err| format!("write error: {}", err)) } #[no_mangle] pub fn load_model() -> () { let args: Vec<String> = env::args().collect(); let program = args[0].clone(); if args.len() < 3 { eprintln!("usage: {} <input_file> <output_file>", program); return; } if let Err(err) = process(&args[1], &args[2]) { eprintln!("{}", err) } }
And compiled via
cargo build --target=wasm32-wasi --release
bjorn3 commented on issue #2902:
Does it work if you specify
./test1.txt
and./test2.txt
?
proohit commented on issue #2902:
Unfortunately not.. Same error:
$ wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model ./test1.txt ./test2.txt error opening input ./test1.txt: failed to find a pre-opened file descriptor through which "./test1.txt" could be opened
bjorn3 commented on issue #2902:
Oh, I think I now what is going on. By using
load_model
as entry point, you are skipping wasi-libc's entry point which initializes libpreopen. As it isn't initialized, libpreopen doesn't know how to open files.
proohit commented on issue #2902:
Hmm, this project was meant for another use-case, where it is used as a lib. I was hoping to quickly test it with wasmtime. Is this on purpose that invoked functions skip other necessary entry points?
bjorn3 commented on issue #2902:
Wasi has two execution models:
- command: This is like an executable. There is a single entry point and after the entry point returns you must discard the whole instance. This entry point is the
_start
function declared in wasi-libc which in turn calls the usermain
.- reactor: This is like a library. There is first a call to
_initialize
declared in wasi-libc. After that it is possible to call any user defined function.To compile a reactor with rustc you need to use the unstable
-Z wasi-exec-model=reactor
flag. I am not sure if wasmtime cli supports reactors, but the api does, though it may be necessary to manually call_initialize
. (not sure if wasmtime already automatically does this for your)
proohit commented on issue #2902:
Thanks for your valuable input! That was new to me and actually solved the problem!
Compiling the project with
cargo rustc --release --target wasm32-wasi -- -Z wasi-exec-model=reactor
did the trick. Nowwasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt
results intest2.txt
.
proohit closed issue #2902:
Test Case
smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txtSteps to Reproduce
Just run the wasm file in the same folder as
test1.txt
.
wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt
Expected Results
A new file inside
./
with the nametest2.txt
and the same contents astest1.txt
.Actual Results
$ wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt error opening input test1.txt: failed to find a pre-opened file descriptor through which "test1.txt" could be opened
Versions and Environment
Wasmtime version or commit: 0.26.0
Operating system: Ubuntu 20.04
Architecture: x86_64
Extra Info
This is the example for WASI from https://github.com/bytecodealliance/wasmtime/blob/main/docs/WASI-tutorial.md
Here's the code:
use std::fs; use std::io::{Read, Write}; use std::env; fn process(input_fname: &str, output_fname: &str) -> Result<(), String> { let mut input_file = fs::File::open(input_fname) .map_err(|err| format!("error opening input {}: {}", input_fname, err))?; let mut contents = Vec::new(); input_file .read_to_end(&mut contents) .map_err(|err| format!("read error: {}", err))?; let mut output_file = fs::File::create(output_fname) .map_err(|err| format!("error opening output {}: {}", output_fname, err))?; output_file .write_all(&contents) .map_err(|err| format!("write error: {}", err)) } #[no_mangle] pub fn load_model() -> () { let args: Vec<String> = env::args().collect(); let program = args[0].clone(); if args.len() < 3 { eprintln!("usage: {} <input_file> <output_file>", program); return; } if let Err(err) = process(&args[1], &args[2]) { eprintln!("{}", err) } }
And compiled via
cargo build --target=wasm32-wasi --release
Timmmm commented on issue #2902:
I'm also getting a very similar error. I'm building a very simple Rust WASI binary not in reactor mode, that tries to opens a file.
I start it in command mode via Node - see code below.
I get the same
failed to find a pre-opened file descriptor
error, but I don't want to switch to "reactor" (why didn't they call this "library"?) mode. I don't understand why this still happens though because surely I am using the_start
entry point which should initialise thislibpreload
library?(Sorry to slightly hijack this issue, but there's not much on the internet about this.)
import { WASI } from "node:wasi"; import { readFile } from "node:fs/promises"; import { join } from "node:path"; async function main() { const wasm = await WebAssembly.compile( await readFile(join(__dirname, "server.wasm")), ); const wasi = new WASI({ env: { RUST_BACKTRACE: "1", }, // This option is mandatory. version: "preview1", }); const instance = await WebAssembly.instantiate(wasm, <WebAssembly.Imports>wasi.getImportObject()); wasi.start(instance); } main();
Timmmm commented on issue #2902:
Oh wait... you just need to do this:
const wasi = new WASI({ env: { RUST_BACKTRACE: "1", }, // This option is mandatory. version: "preview1", preopens: { "/": "/", }, });
Sorry for the noise!
Timmmm commented on issue #2902:
For Windows you need this nonsense:
"/": "/", "a:/": "a:/", "b:/": "b:/", "c:/": "c:/", "d:/": "d:/", ...
(Or I guess narrow it down to a specific directory if your application allows that.)
Last updated: Dec 23 2024 at 13:07 UTC