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

fs9p read_file strange behavior (How to detect if ready to read?) #1044

Closed
frvnkliu opened this issue May 18, 2024 · 6 comments
Closed

fs9p read_file strange behavior (How to detect if ready to read?) #1044

frvnkliu opened this issue May 18, 2024 · 6 comments

Comments

@frvnkliu
Copy link

Whenever I create a file in a debian container mountain fs9p, the v86.prototype.read_file function displays some weird behavior.
image
For the first 30 seconds after a file is created this function doesn't work, it'll return a bad promise
image
but then after a little bit of waiting the function works fine. I was wondering if there was someway of checking if a file is ready to be read from v86.

Using Chrome's debugger I found the following:
In the fs9p.read_file:
image
Then in fs9p.Read:
image
I think this is where the issues occurs, here b and c are both 0 so the empty/null list is copied and returned.

Is there someway I can check if a file is ready for download instead of just setting a timeout to an arbitrary time?

@SuperMaxusa
Copy link
Contributor

Did you try run sync (or mount -o remount,sync / before) after creating file?
And can you also to try changing cache=fscache to cache=loose or cache=none?

echo "Running: mount -t 9p -o cache=fscache ${ROOT} ${rootmnt}"
mount -t 9p -o cache=fscache ${ROOT} ${rootmnt}

@frvnkliu
Copy link
Author

Did you try run sync (or mount -o remount,sync / before) after creating file? And can you also to try changing cache=fscache to cache=loose or cache=none?

echo "Running: mount -t 9p -o cache=fscache ${ROOT} ${rootmnt}"
mount -t 9p -o cache=fscache ${ROOT} ${rootmnt}

I have not tried to run sync yet, but I will try that soon.

I am currently using the v86/tools/docker/debian to create my image, so I will also try changing cache to loose or none

cmdline: "rw init=/bin/systemd root=host9p console=ttyS0 spectre_v2=off pti=off"

I also write run the line above when initializing my v86 instance, but I'm notsure where I got from. Is it possible that this is causing issues?

var emulator = new V86({
    	screen_container: document.getElementById("screen_container"),
    	wasm_path: "./libs/v86.wasm",
        bios: { url: `${V86_ROOT}/bios/seabios.bin` },
        vga_bios: { url: `${V86_ROOT}/bios/vgabios.bin` },
        autostart: true,
        memory_size: 512 * 1024 * 1024,
        vga_memory_size: 8 * 1024 * 1024,
        bzimage_initrd_from_filesystem: true,
        cmdline: "rw init=/bin/systemd root=host9p console=ttyS0 spectre_v2=off pti=off",
        filesystem: {
            basefs: {
                url: `${V86_ROOT}/images/debian-base-fs.json`,
            },
            baseurl: `${V86_ROOT}/images/debian-9p-rootfs-flat/`,
        },
        autostart: true,

    });```

@SuperMaxusa
Copy link
Contributor

SuperMaxusa commented May 21, 2024

Sorry for the late reply, that's weird that for you file is opened after 30 seconds, for example, I got maximum 5 seconds timeout on Arch and Buildroot Linux. I have some ideas about vm.dirty_writeback_centisecs (https://docs.kernel.org/admin-guide/sysctl/vm.html#dirty-writeback-centisecs), default value is 500 centiseconds = 5 seconds (at least on Arch), maybe Debian has a some different value?

This can be checked with: cat /proc/sys/vm/dirty_writeback_centisecs

I also write run the line above when initializing my v86 instance, but I'm notsure where I got from. Is it possible that this is causing issues?

Probably no, spectre_v2=off pti=off - it's disables an kernel mitigations, root=host9p - needed to mount root via boot-9p hook, other options in cmdline and V86 construstor look fine.

@frvnkliu
Copy link
Author

Hi, I tried changing the cache to none and I got the following error:
image

I just checked the value of the timeout and its supposed to be 0.5 seconds.
image

@SuperMaxusa
Copy link
Contributor

SuperMaxusa commented May 22, 2024

I just checked the value of the timeout and its supposed to be 0.5 seconds.

I made a mistake in the previous message: 5 seconds = 500 centiseconds, and seems that your value is set to default

I wrote a small script to check the availability of a file by time:

var testInterval, timer, hasError, filePath;

var test9PFS = function() { 
    window.emulator.read_file(filePath).catch((e) => {
        console.error(`File not available on ${++timer} seconds`);
        hasError = true;
    }).then(() => {
        if (!hasError) {
            console.log("File available");
            clearInterval(testInterval);
        } else {
            hasError = false;
        }
    }); 
};

var startTest = function() {
    testInterval = null, timer = 0, hasError = false, filePath = "/root/testfile";
    window.emulator.keyboard_send_text(`echo testdata > ${filePath} # AUTOMATED\n`);
    testInterval = setInterval(test9PFS, 1000);
};

First test: all default settings, as you said, there is over 30 seconds timeout. And I had a some attention about vm.dirty_expire_centiseconds, which value is 3000 centiseconds = 30 seconds, https://stackoverflow.com/questions/11884650/small-file-not-committed-to-disk-for-over-a-minute

deb1

Second test: reduced vm.dirty_writeback_seconds to 1 second, I got 5 second timeout (probably it's because I didn't change vm.dirty_writeback_centisecs?)

deb2

Third test: remount 9p as sync filesystem (or you can use a O_SYNC flag for open() syscall in your program), file opens immediately.

deb3


Some ideas:

  • try testing on newer versions of Debian, for example: bookworm (or if you build a v86 with afdac89, you can try a trixie)
  • if it's useful, you can use a 9p-write-end event to catch the end of a file write:

    v86/src/browser/main.js

    Lines 1742 to 1751 in c69cbd7

    emulator.add_listener("9p-write-end", function(args)
    {
    stats_9p.write += args[1];
    $("info_filesystem_bytes_written").textContent = stats_9p.write;
    if(!stats_9p.files[0])
    {
    $("info_filesystem_last_file").textContent = args[0];
    }
    });

@copy
Copy link
Owner

copy commented May 31, 2024

I'll close this, as the time the guest OS decides to buffer writes is not related to v86 (but feel free to reopen if you think anything in v86 could be changed).

Also, I'd probably accept a PR that changes 9p-write-end if there's anything missing from that event that'd be useful for you.

@copy copy closed this as completed May 31, 2024
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

No branches or pull requests

3 participants