Stream: git-wasmtime

Topic: wasmtime / issue #2902 failed to find a pre-opened file d...


view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 10:40):

proohit labeled issue #2902:

Test Case

smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txt

Steps to Reproduce

Just run the wasm file in the same folder as test1.txt.

Expected Results

A new file inside ./ with the name test2.txt and the same contents as test1.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

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 10:40):

proohit opened issue #2902:

Test Case

smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txt

Steps to Reproduce

Just run the wasm file in the same folder as test1.txt.

Expected Results

A new file inside ./ with the name test2.txt and the same contents as test1.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

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 10:43):

proohit edited issue #2902:

Test Case

smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txt

Steps 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 name test2.txt and the same contents as test1.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

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 10:46):

bjorn3 commented on issue #2902:

Does it work if you specify ./test1.txt and ./test2.txt?

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 11:23):

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

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 12:01):

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.

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 12:20):

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?

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 13:18):

bjorn3 commented on issue #2902:

Wasi has two execution models:

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)

https://github.com/WebAssembly/WASI/issues/13

https://github.com/rust-lang/rust/pull/79997

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 15:09):

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. Now wasmtime run --dir=. smartcore_wasi_lib.wasm --invoke load_model test1.txt test2.txt results in test2.txt.

view this post on Zulip Wasmtime GitHub notifications bot (May 12 2021 at 15:09):

proohit closed issue #2902:

Test Case

smartcore_wasi_lib.wasm - https://easyupload.io/7l8u6z
test1.txt

Steps 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 name test2.txt and the same contents as test1.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

view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2024 at 20:17):

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 this libpreload 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();

view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2024 at 20:20):

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!

view this post on Zulip Wasmtime GitHub notifications bot (Sep 20 2024 at 20:35):

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: Nov 22 2024 at 16:03 UTC