Repository navigation
sea: mount the SEA VFS in workers at layer 0 - #67239
Conversation
|
Review requested:
|
|
Welcome to Node.js, and thank you for your first contribution! Before review, please take a moment to read:
Please make sure every commit is signed off. For a first pull request, GitHub Actions require collaborator approval and Jenkins CI must be started by a collaborator or triager, so an initial wait is normal. |
|
I'm not entirely sure this is the totally right approach. That being said, I'm also not entirely sure that's a bad thing. 😄 If anything I'm wondering whether I'll be looking at this in detail during the coming week. |
|
Thanks for picking this up, and for the worker test in the SEA fixture: it tests exactly what #67223 is about, so please keep it. Having looked at this in detail, I think the fix should go one step further and put the SEA VFS at layer 0, whatever serves it, instead of reserving layer 1 for assets. Why layer 0
Whether the SEA uses
In In a worker's Once |
4894f33 to
24aa85a
Compare
|
@pipobscure Thanks for the detailed review, that makes sense. Treating I've updated the PR:
One question: I took "every SEA" literally, so I squashed everything into one commit. I've only tested on Linux so far, so if someone can try it on Windows (where the original issue showed up), that would be great. |
Yeah, I don't think allowing it makes sense as generally if you create an SEA, you want to control over what's run, so enabling this is like an escape-hatch which is risky. I'll ping a few other people this week to go over this as well and give it another review as well. |
Thanks, I’ll wait for the other reviews |
pipobscure
left a comment
There was a problem hiding this comment.
LGTM. @mcollina let's have a look at this one on Tuesday
|
Can you rebase on the latest main please, then I can approve that and get it in. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #67239 +/- ##
==========================================
+ Coverage 90.73% 90.74% +0.01%
==========================================
Files 798 798
Lines 280076 280117 +41
Branches 53880 53892 +12
==========================================
+ Hits 254123 254190 +67
+ Misses 16259 16215 -44
- Partials 9694 9712 +18
🚀 New features to boost your workflow:
|
A single executable application built with "useVfs" mounted the VFS serving its "assets" in the main thread only, at a mount point numbered in mount order, so a worker started from a script among the assets could not load it. On Windows this failed as an invalid package.json at \.\nul\package.json, because paths under the NUL device open it. "useVfs" is the --vfs-load of a single executable application: its "assets" or its "vfsArchive" archive are the source, and its "main" is the entry point. Mount it at layer 0, the mount point reserved for the --vfs-load source, whichever provider serves it, and mount it in workers too, as was already done for an archive. Other mounts are numbered from 1, as everywhere else. To keep layer 0 free, reject --vfs-load in every single executable application rather than only in one built with "vfsArchive": its entry point is fixed, and resolving modules against its files is what "useVfs" already does. --build-sea refuses it in "execArgv", and the executable at startup when it comes from --node-options or from the execArgv of a worker. A worker started from a path into a VFS that is not mounted in it, such as one mounted with vfs.mount() in its parent, now fails with ERR_VFS_NOT_MOUNTED. Fixes: nodejs#67223 Assisted-by: a coding agent Signed-off-by: Manjeet Singh <024manjeetsingh@gmail.com>
Remove two comments in EnvironmentOptions::CheckOptions() that repeat what the code and the error message already say, and move the note that --vfs-load cannot be used in a single executable application out of the "Worker threads" section, since it applies to every SEA. Refs: nodejs#67223 Assisted-by: a coding agent Signed-off-by: Manjeet Singh <024manjeetsingh@gmail.com>
3dcd62c to
77c4ffb
Compare
|
@pipobscure Rebased on the latest main. mcollina's compile cache change (#66768) touched the same code, so I adjusted it to fit this PR:
All SEA, VFS, worker and compile cache tests pass locally (Linux). @mcollina the rebase made your approval stale. Could you take another look? The only changes since your review are the rebase and the compile cache adjustments above. |
|
Landed in 1b99d7c |
Fixes: #67223
A single executable application built with
"useVfs": trueand plain"assets"mounts its VFS only in the main thread, at a mount point numberedin mount order. A worker started from a path into it, such as a worker script
bundled as an asset, finds nothing there. On Windows the failure is
especially confusing: paths under
\\.\nulopen the NUL device, so the loader"finds" the file and then rejects
\\.\nul\package.jsonas an invalidpackage.json (
ERR_INVALID_PACKAGE_CONFIG).#66709 already mounts the VFS in workers when it is backed by
"vfsArchive",using the mount point reserved for
--vfs-load. This does the same for"assets":same in every thread whatever else a thread mounts. Other mounts are
numbered from 2 in that case. The decision is recorded in C++ as an internal
[sea_vfs_assets]option next to[sea_vfs_archive], so that a worker of anon-SEA process still does not load
internal/vfs/sea.initSeaVfsInWorker()for either kind of SEA VFS.For a VFS mounted with
vfs.mount(), which a worker cannot see, the workernow fails with a new
ERR_VFS_NOT_MOUNTEDinstead of whatever the real filesystem answers. The check only runs for a filename containing
vfs, so otherworkers do not load the VFS modules.
Tests:
test/sea/test-single-executable-application-vfs.js: the fixture nowstarts a worker from a script bundled as an asset, which reads an asset and
requires a module next to it, and checks it sees the same
__dirname.test/parallel/test-vfs-worker-not-mounted.js: a worker started from avfs.mount()path getsERR_VFS_NOT_MOUNTED, and a real path that merelycontains
vfsstill runs.Verified locally on Linux x64 (Ubuntu 24.04, GCC 13):
tools/test.py parallel/test-vfs* parallel/test-worker* parallel/test-bootstrap-modules sea/*passes (319 tests, no SEA test skipped).
tools/test.py --worker parallel/test-bootstrap-modulespasses, so a workerof a non-SEA process still loads no VFS module.
lib/changes, both new tests fail: the SEA worker getsCannot find module '/dev/null/vfs/1/worker.js', the Linux form of thereported error.
make lint-js,make lint-mdand cpplint pass on the changed files.I could not test on Windows, where the original report comes from.
AI assistance was used; I have reviewed the change and run the tests above.