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

Can't mount root / directory #2040

Closed
dex4er opened this issue Jan 21, 2014 · 11 comments
Closed

Can't mount root / directory #2040

dex4er opened this issue Jan 21, 2014 · 11 comments

Comments

@dex4er
Copy link

dex4er commented Jan 21, 2014

I can use root directory as a subdirectory in FS tree:

var Module = {};
Module.preRun = function() {
  FS.mkdir('root');
  FS.mount(NODEFS, { root: '/' }, 'root');
  FS.chdir('root/' + process.cwd());
}

but following code breaks on creating fake /dev/* and /tmp:

var Module = {};
Module.preRun = function() {
  FS.mount(NODEFS, { root: '/' }, '/');
}

All I want is to map real filesystem but some special directories like /dev.

@inolen
Copy link
Collaborator

inolen commented Jan 21, 2014

We currently by default mount an instance of MEMFS at root as part of the static initialization (staticInit
in library_fs.js), and there is no unmount support unfortunately.

@jabooth
Copy link

jabooth commented Mar 31, 2017

Just to revisit this, I'm currently working on using Emscripten to compile LaTeX related tools for Node, the idea being a single cross-platform binary that just works. My first attempt was with ChkTeX, a LaTeX linter here:

/~https://github.com/jabooth/chktex.js

The problem I have is that the C code I am wrapping may do arbitrary R/W to the filesystem and I want that to be completely transparently mapped into the virtual FS.

I ended up doing similar workarounds to svaarala/duktape#355, where I basically manually monkey-patch fopen and friends to re-route to a different file:
/~https://github.com/jabooth/chktex.js/blob/master/Utility.h#L36

That's OK for something as small as ChkTeX, but intractable for larger projects.

It feels like this is something that must be solvable at the Emscripten FS layer pretty simply, but my only thought on how to do it would be to mount the NODEFS host / at virtual / which is currently not permitted.

Any suggestions for how to solve this transparent FS mapping problem for Node FS targets within the current confides of how Emscripten works @inolen?

@CMCDragonkai
Copy link

CMCDragonkai commented Sep 6, 2017

I hope to get some clarification on this issue. Basically memfs is mounted in / and there's no way to change this. This is because of what exactly? Device support? Does this mean memfs implements things like /dev (such as /dev/stderr, /dev/urandom) and /proc.. etc.

I'm in the situation where either:

  1. Need to be able to mount my own in-memory VirtualFS on / (And I'll have all of the necessary calls and devices implemented). Where this virtual fs comes from an external module. For example see BrowserFS or my own VirtualFS. The reason for this is that I can have more control of the in-memory fs operations, for some custom behaviour that I need. (Such as sharing a single in-memory fs instance across multiple emscripten modules and non-emscripten modules).
  2. Use Emscripten's memfs at / but I need to export the entire emscripten FS api outside of emscripten and present it to other Javascript modules.

Which way is possible, and how? The documentation shows usages of EM_ASM, but doesn't seem to show how objects inside the EM_ASM block can get exported through the C functions (either directly or via embind). And when I was introspecting the Module object, even when forcing the linking of FS module, I wasn't able to find any of the fs functions on the Module object.

@kripken mentions technical limitations here #5237 (comment) but what are these technical limitations? So we can try to work it out.

Also what about flock and other similar calls? How does emscripten map these to JS calls when using something like nodefs other than providing a binding to C++ like how node-fs-extra package does.

@kripken
Copy link
Member

kripken commented Sep 6, 2017

It might be what @inolen wrote a few comments up (we mount the root already, and there is no unmount support). It's possible no one currently has a good understanding of those technical limitations, as it's pretty stable code and no one has worked on it recently. I'd recommend diving into the code to see.

(If it is just that initial mount, it might be possible to add a flag to not do it, and leave all mounting to the user. Maybe worth experimenting with.)

@inolen
Copy link
Collaborator

inolen commented Sep 6, 2017

IIRC the technical limitations revolve around supporting the default set of devices once a different filesystem is mounted at root:

/~https://github.com/kripken/emscripten/blob/master/src/library_fs.js#L1257

@juj
Copy link
Collaborator

juj commented Sep 7, 2017

On Windows the MSYS environment has things like /dev/... and /usr/... etc. which are MSYS's own virtual things, and then it mounts the C: drive to at /c/.... Would doing the same work if you mounted drive root directories to /c/, /d/, etc. and e.g. on Linux perhaps the global root to /host/? Is there something special why the native filesystem root must exactly coincide with the MEMFS filesystem root? (something does not work if that is not the case?) Or is it more about convenience? If so, how would you support Windows which does not have a root, or is this about doing Unix specific programs?

@CMCDragonkai
Copy link

@juj I'm only interested in the unix (linux) environment. I don't know how emscripten is supposed to react in MSYS?

Basically I need to share the "filesystem instance" between what emscripten is exposing to its own module, and my other modules which may not be emscripten compiled. I had written a in-memory FS already in support of this, but then I found that emscripten has a memfs. Anyway that's why I asked about the 2 options in my previous comment: #2040 (comment)

@CMCDragonkai
Copy link

CMCDragonkai commented Sep 12, 2017

I found the point where you can make root filesystems pluggable.

It's here: /~https://github.com/kripken/emscripten/blob/12d47b086d139fbd7c5b21e1c30522e63366e3d5/src/library_fs.js#L1387

FS.mount(MEMFS, {}, '/');

This results in a call to this at "program load time":

/~https://github.com/kripken/emscripten/blob/12d47b086d139fbd7c5b21e1c30522e63366e3d5/src/library_fs.js#L556

var mountRoot = type.mount(mount);

If the usage of MEMFS there was parameterised, then it would be possible to instantly allow any rootfs implementation to take over, either from the existing FS implementations, or allow users to link in new FS implementations via --js-library.

The most easiest solution is to make MEMFS a compile time macro that can be set from settings.js, however I actually need to feed in the right FS implementation at runtime ("program load time"). So I can use prejs and postjs to encapsulate the emscripten module and then parameterise the rootfs implementation. If the macro setting did not need any kind of resolution verification, then the macro could be set to a global variable, that is expected to exist at the Module context at runtime.

My current hack right now is to "overlink" the library_memfs.js, and fill in my own fs implementation. The only function used at "program load time" is mount called from FS.staticInit.

@stale
Copy link

stale bot commented Sep 12, 2019

This issue has been automatically marked as stale because there has been no activity in the past 2 years. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant.

@stale stale bot added the wontfix label Sep 12, 2019
@stale stale bot closed this as completed Sep 19, 2019
@DavidLudwig
Copy link

DavidLudwig commented Apr 26, 2020

I've been running into this issue, too, and wonder if a new, 'Union Filesystem' / unionfs extension to Emscripten might help. In this case, both memfs and the native filesystem could be mounted at '/'. There would, obviously, be opportunity for collisions, but perhaps dealing with these could be moved into separate, maybe-smaller issues?

Also, given that this bug was marked Closed due to being stale, might new Github Issues be relevant, here?

@ceifa
Copy link

ceifa commented Jul 23, 2021

One year later and I ran into the same problem :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants