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

Support libfuse2 and libfuse3 at the same time with dlopen? #60

Closed
haampie opened this issue Mar 31, 2021 · 12 comments
Closed

Support libfuse2 and libfuse3 at the same time with dlopen? #60

haampie opened this issue Mar 31, 2021 · 12 comments

Comments

@haampie
Copy link
Contributor

haampie commented Mar 31, 2021

Now that squashfuse_ll.a is a library on its own, it can be used to create self-mounting squashfs executables (e.g. appimage / xar). When distributing those, the problem is we don't know whether the target machine has libfuse2 or 3, and right now that is fixed at compile-time.

Can we use dlopen to figure this out at runtime instead?

@probonopd
Copy link
Contributor

Now that squashfuse_ll.a is a library on its own, it can be used to create self-mounting squashfs executables (e.g. appimage / xar).

Is there an example somewhere for how to do that?

@haampie
Copy link
Contributor Author

haampie commented Mar 31, 2021

I haven't done that yet, you can use the squashfuse_ll.pc package config file to get the ll.h header & libsquashfuse_ll.{a,so} lib, and then copy the bits you need from ll_main.c to your own project.

@chipturner
Copy link
Collaborator

I would suggest finding some other FUSE filesystem that does fuse2/fuse3 at runtime. It seems like it would probably be an invasive (perhaps impossible, given data structure changes). But maybe it's possible and someone has done it. But I don't want to be first :)

@haampie
Copy link
Contributor Author

haampie commented Mar 31, 2021

Ok, that's understandable. I think I'll just happily link against a particular version of libfuse instead of dlopening anyways.

@haampie haampie closed this as completed Mar 31, 2021
@vasi
Copy link
Owner

vasi commented Mar 31, 2021

Yeah, it's probably just easier to build a static binary. Is there a reason you can't do that in your use case?

@haampie
Copy link
Contributor Author

haampie commented Mar 31, 2021

The issue is licensing; libfuse is LGPL which means

If you statically link against an LGPLed library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.

This can be problematic for users.

Edit: potentially though I could see how you could be compliant to the LGPL license without have to license your own squashfs sources in these self-mounting binaries LGPL... but IANAL.

@vasi
Copy link
Owner

vasi commented Mar 31, 2021

Mmm, that makes sense. The good news is that use of fuse functions/constants is pretty isolated in squashfuse. So you could imagine just compiling ll.c twice with different headers and function-prefixes, and then your wrapper would just have to dlopen libfuse and call the right entrypoint.

I guess you'd also want to move a bunch of ll_main.c into ll.c, but honestly that seems like the right decision anyhow? @haampie does your code that uses libsquashfuse_ll end up duplicating most of ll_main.c?

@haampie
Copy link
Contributor Author

haampie commented Mar 31, 2021

That sounds like an idea indeed :)

And yes, moving things from ll_main to ll would make sense. If ll_main could just do argument parsing that'd be nice.

I've made a minimal working example here: https://github.com/haampie/appimage_runtime/ hacked together from AppImageKit's runtime.c and ll_main.c. Note that the spack commands don't work yet because PRs are pending, but installation should be reasonably easy from start to finish soon (tm).

@haampie
Copy link
Contributor Author

haampie commented Apr 1, 2021

Hm, statically linking libfuse is not a good idea because the path to the setuid binary fusermount (FUSERMOUNT_DIR) is set compile-time, so it wouldn't be portable. Shared linking is more portable.

@chipturner
Copy link
Collaborator

I am concerned all of these options add a bit of complexity for fairly niche use case. What systems only have libfuse2? libfuse3 is four years old and the last release of libfuse2 was Jan 2019.

@haampie
Copy link
Contributor Author

haampie commented Apr 1, 2021

Probably @probonopd can correct me, but appimagekit is rather conservative with dependencies (compiling against old libc etc) so that they can distribute one binary that works everywhere assuming abi compatibility. To support old systems they dlopen libfuse2, but now there are new distro's that might not have libfuse2 installed anymore, so they might need to add a hack to support both. I guess libfuse is their only dep that is breaking abi

@vasi
Copy link
Owner

vasi commented Apr 1, 2021

How bad would it be to just build separate binaries, and have a small wrapper choose between them at runtime? Most Linux games do something like 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

No branches or pull requests

4 participants