SerCeMan / jnr-fuse

FUSE implementation in Java using Java Native Runtime (JNR)
MIT License
365 stars 87 forks source link

Attempting to load liblibfuse.so.2.so #81

Open overheadhunter opened 5 years ago

overheadhunter commented 5 years ago

I just noticed that the lib prefix as well as the .so suffix is appended twice when you attempt to load the fuse library on Linux here:

https://github.com/SerCeMan/jnr-fuse/blob/0f533a23553ba8f39714f719a8eb48dd3d8783a8/src/main/java/ru/serce/jnrfuse/AbstractFuseFS.java#L41-L43

You pass in the full file name to jnr.ffi, which will then try to find a file named liblibfuse.so.2.so(.[0-9]+)?.

I think it is best to just invoke loader.load("fuse"); on Linux.

At the same time I'm wondering how it could have ever been working before (which it did). This doesn't make any sense to me.

Workaround: ln -s libfuse.so.2 liblibfuse.so.2.so not feasible for endusers, but helps me during development until this is fixed :wink:

SerCeMan commented 5 years ago

Hey, @overheadhunter!

Thanks for noticing, I'll take a look into this. Interestingly, it works well on CI without any issues.

SerCeMan commented 5 years ago

I think, one of the possible explanations is that jnr used to fail to "identify" the OS, so the switch would fall through to the default section.

overheadhunter commented 5 years ago

Possibly. We distribute our software as an Appimage which has some different environment variables that might cause the app to use the default branch of that switch-statement... :thinking:

SerCeMan commented 5 years ago

Hey, @overheadhunter! From looking at https://github.com/jnr/jnr-ffi/blob/master/src/main/java/jnr/ffi/provider/jffi/NativeLibrary.java#L79, it seems like the first call should be end up calling dlopen("libfuse.so.2"). Do you know what can be the reason for this call to fail?

I'll add a fallback call to try fuse anyways since there is a possibility that one of them fails.

SerCeMan commented 5 years ago

@overheadhunter As a quick workaround, you could try something like the following with the current version:

LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/full/path/to/libfuse.so.2" java -cp ...
SerCeMan commented 5 years ago

Hey, @overheadhunter! Could you verify the fix from master? If it fixes the issue, I can publish a new version.

overheadhunter commented 5 years ago

it seems like the first call should be end up calling dlopen("libfuse.so.2").

But this assumes that libfuse.so.2 is in the current working directory, correct? Only the second...nth attempt to dlopen the lib try it with an absolute path.


I will do some experiments with both, the LD_LIBRARY_PATH as well as the master branch on Wednesday.

overheadhunter commented 4 years ago

I just started my debugger with a breakpoint in this line and found out that files inside /lib/x86_64-linux-gnu such as libfuse.so.2 are missing while other files such as libdrm_tegra.so.0.0.0 are listed even if they do not exist.

This lead me to the assumption that /lib/x86_64-linux-gnu is somehow different due to Flatpak's sandbox (I'm running the Flatpak version of IntelliJ here - and we plan to distribute our application as a Flatpak itself, too).


Playing around with LD_LIBRARY_PATH as well as java.library.path does help locating libfuse. However, fuse mount fails. Maybe due to missing transitive .so dependencies..?

fuse_main_real returns 1:

Caused by: ru.serce.jnrfuse.FuseException: Unable to mount FS, return code = 1
    at ru.serce.jnrfuse.AbstractFuseFS.mount(AbstractFuseFS.java:277)

I cloned your repo and built 0.5.4-SNAPSHOT. Behaviour is unchanged. I set a breakpoint here and could see that this branch the fallback routine was triggered but threw an UnsatisfiedLinkError itself.

Sadly the fix doesn't help. That doesn't mean that you should rollback you change, at least it will now construct the correct regex. Also, I verified that it works correctly on non-Flatpak environments.


I believe the root cause is somewhere else. Feel free to close this issue, as I have a feeling there is nothing you can do about it as long as fuse doesn't work inside Flatpak's sandbox...