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

Initial NODERAWFS implementation #6008

Merged
merged 37 commits into from
Jan 16, 2018
Merged

Conversation

saschanaz
Copy link
Collaborator

@saschanaz saschanaz commented Dec 31, 2017

Fixes #5266.

This removes the need for emscripten-compiled CLI tools to manually mount NODEFS and map all file paths.

-s NODERAWFS=1 overwrites on FS object and works as an in-place replacement when on Node.js, otherwise the existing virtual filesystem is provided.

Node.js supports integer flags but it depends on native system constants, which are different from values on struct_info.compiled.json
@kripken
Copy link
Member

kripken commented Jan 3, 2018

Nice! This is simpler than I thought it would need to be.

More testing (of all the file operations that are practical to test) and documentation would be good here.

@kripken
Copy link
Member

kripken commented Jan 3, 2018

Also we should test it in core, so all compilation modes get checked.

@juj
Copy link
Collaborator

juj commented Jan 4, 2018

Should this disable --embed-file and --preload-file to be used in conjunction, since this actually backs on a physical filesystem that is already persistently prepopulated, and not on to a virtual filesystem that would need to be loaded up at every startup. Therefore virtual filesystem packages would end up unpacking the contents of the .data files again and again to a physical location on disk. Perhaps a mutual incompatibility check would be good here?

@saschanaz
Copy link
Collaborator Author

It seems the truncate test does not work with root permission.

f = open("/", O_RDONLY);
f2 = open("/", O_RDONLY);
f = open(".", O_RDONLY);
f2 = open(".", O_RDONLY);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we leave a form that checks against / in non-NODERAWFS form? I think we'd want to retain that, it's an important invariant of MEMFS that / root is predictable.

);
assert(open("/working/test.txt", O_RDONLY | O_CLOEXEC) != -1);
assert(open("test.txt", O_RDONLY | O_CLOEXEC) != -1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of /working/ could be seen as changing the test, although searching through the tests/ subdirectory, it does look like there's still a couple of places where we explicitly test the /working/test.txt form. I think we'd like to ensure that this is tested, since this does change absolute to relative, which sometimes has different behavior. Perhaps a

#ifdef NODERAWFS
#define ROOT ""
#else
#define ROOT "/"
#endif

...

assert(open(ROOT "working/test.txt", O_RDONLY | O_CLOEXEC) != -1);

or similar, to keeping testing behavior of absolute paths, while retaining the relative test for NODERAWFS?

(I'm not sure how important specifically the absolute root path property was when the original test was being crafted, but I think it's good to keep it as close to original as possible, perhaps only adding new cases)

@@ -4582,20 +4599,43 @@ def process(filename):
}
''', 'at Object.write', js_engines=[NODE_JS], post_build=post) # engines has different error stack format

def test_noderawfs(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests like these two that don't depend on the compiler mode should be in other (otherwise we run the same test in each mode)

src/settings.js Outdated
@@ -382,6 +382,10 @@ var NO_FILESYSTEM = 0; // If set, does not build in any filesystem support. Usef
var FORCE_FILESYSTEM = 0; // Makes full filesystem support be included, even if statically it looks like it is not
// used. For example, if your C code uses no files, but you include some JS that does,
// you might need this.
var NODERAWFS = 0; // This dynamically disables virtual filesystem when the build result runs on Node.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps this should just make the build node.js-only, that seems simpler? is there a benefit to letting it run on non-node with different behavior?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NODERAWFS only replaces low-level APIs, otherwise it depends on original FS methods including FS.read/writeFile. FS.ensureErrnoError, FS.nextfd, etc. I think there is no value to make it node.js-only when we still depend on original FS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might avoid some possible confusion, though. To be clear, I'm suggesting that when NODERAWFS is enabled, the build will throw at runtime if it is loaded in anything else than node.js.

Otherwise, the possible confusion that worries me is that the build is run in node and in another shell, and they produce very different results. That's currently something that should not happen, which shell you are in should not matter.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which shell you are in should not matter

Yeah... it can be confusing in other shell environments. We may make it throw first and see what's going on.

Copy link
Collaborator Author

@saschanaz saschanaz Jan 14, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated but probably we cannot run a failure test on CI as 1. we only have Node.js 2. AFAIK the browser test does not support failure test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, and yeah, makes sense about testing.

This PR looks good to me now, just one last thing, please update the comment here in settings.js to say it will throw if not in Node.js.

src/settings.js Outdated
@@ -385,7 +385,7 @@ var FORCE_FILESYSTEM = 0; // Makes full filesystem support be included, even if
var NODERAWFS = 0; // This dynamically disables virtual filesystem when the build result runs on Node.js
// and directly depends on behaviors of Node.js File System API.
// The initial working directory will be same as process.cwd() instead of VFS root directory.
// The VFS becomes only available for non-Node.js environment.
// The build result will throw when it runs on non-Node.js environment.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one? @kripken

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but sorry, I should have been more clear. It's the first statement I think is confusing,

"This dynamically disables virtual filesystem when the build result runs on Node.js"

How about text like "This mode is intended for use with Node.js (and will throw if the build is run in another engine)" at the start, removing "when the build runs on Node.js" (since that is the only intended use).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, just pushed a commit for that 😃

@kripken kripken merged commit 99e4fc3 into emscripten-core:incoming Jan 16, 2018
@kripken
Copy link
Member

kripken commented Jan 16, 2018

Great, thanks!

@kripken
Copy link
Member

kripken commented Jan 17, 2018

I think I see why we missed the test failures here. The last commits are ci skip, so perhaps the breakage starts in them, and also, it looks like github looks at the last commit for showing the build status, it doesn't look back past any ci skips, which makes it harder to see what's going on.

@saschanaz saschanaz deleted the noderawfs branch January 17, 2018 02:58
@saschanaz
Copy link
Collaborator Author

Oops, are some tests failing on the bots? Strange, I didn't thought the last ci-skipping commits can break anything... (e473771 added else branch for non-Node.js and 1574770 only changed comments)

@saschanaz
Copy link
Collaborator Author

test_fs_stream_proto is failing but it seems it's rather related with #5967 rather than this one, as I think this PR has never touched it.

@kripken
Copy link
Member

kripken commented Jan 17, 2018

Hmm, I bisected test_fs_stream_proto to this commit, but maybe I did something wrong...

I also bisected the other failures (partial list here) to this commit. The error on them is TypeError: Cannot read property 'O_APPEND' of undefined on NODEFS so it does seem related.

@saschanaz
Copy link
Collaborator Author

saschanaz commented Jan 17, 2018

Git blame says the last change in that line is from 9fc522a, which definitely causes type error on Python 3. I wonder why the change. cc: @juj

(A fix is on #6098)

@juj
Copy link
Collaborator

juj commented Jan 17, 2018

Git blame says the last change in that line is from 9fc522a, which definitely causes type error on Python 3. I wonder why the change. cc: @juj

Ops, very sorry about this breakage - that was one of those "this is just way too trivial to need a review" so I pushed it in direct. The reason for that change is that the test was failing on Windows where it was writing \r\n newlines to the output, but then tested the file size of the result, which differed from expected on Windows because of those \rs adding in the size. Writing in binary mode causes Windows to omit \r\n but do \n newlines instead. Sorry, I was not familiar with the typedness of these writes on Python 3, that's very good to know.

@aheejin
Copy link
Member

aheejin commented Jan 19, 2018

This is currently breaking out waterfall Mac bots:
asm2wasm log
wasm backend log

Doesn't look like the CI has mac bots. Could you test them on mac?

@kripken
Copy link
Member

kripken commented Jan 19, 2018

Sadly I don't think travis has mac bots...

Looking at the last error in the second link, it says it's node 8.9.3 so it's probably not a version issue. Likely it really is an OS difference, and NODERAWFS is sensitive to such things. We'd need to debug it on mac I guess. If no one thinks they can get to that soon, we could disable the NODERAWFS tests on mac for now, and maybe update the docs to warn.

@aheejin
Copy link
Member

aheejin commented Jan 20, 2018

I disabled the tests. Not sure which doc to update though.

@dschuff
Copy link
Member

dschuff commented Jan 20, 2018

Side note, Travis actually does have mac bots: see e.g. https://github.com/WebAssembly/wabt/blob/master/.travis.yml

@saschanaz
Copy link
Collaborator Author

Looking at the logs, it seems append mode doesn't work on macOS. I don't have any macOS access but how about filing issues on Node.js too?

@kripken
Copy link
Member

kripken commented Jan 22, 2018

Not sure which doc to update though.

I think the best we have is the settings.js description. I'll update that.

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

Successfully merging this pull request may close these issues.

None yet

5 participants