From 73fc2ae731a4ef972c16efb31a30da9e9a8645c6 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sat, 2 May 2026 00:07:57 -0500 Subject: sanitychecks: probe libfuse3 via dlopen, accept .so.4 Fedora 44 and Arch ship libfuse3.so.4; the static path list only checked .so.3 / unversioned .so, so the sanity check warned "libfuse3 not found" on systems where FUSE actually works. Use dlopen() with RTLD_NOLOAD then RTLD_LAZY against libfuse3.so.{4,3,} so the dynamic loader resolves through /etc/ld.so.cache and picks up any SOVERSION the distro ships. Fallback path list extended with .so.4 for sandboxes that block dlopen. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/src/sanitychecks.cpp | 49 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/src/sanitychecks.cpp b/src/src/sanitychecks.cpp index b18ea43..d10baac 100644 --- a/src/src/sanitychecks.cpp +++ b/src/src/sanitychecks.cpp @@ -7,6 +7,8 @@ #include #include +#include + namespace sanity { @@ -17,24 +19,45 @@ int checkMissingFiles() log::debug(" . checking Linux dependencies"); int n = 0; - // Check for FUSE (check both unversioned .so and versioned .so.3 — on - // Debian/Ubuntu the unversioned symlink is only in libfuse3-dev). - static const char* fusePaths[] = { - "/usr/lib/libfuse3.so", - "/usr/lib/libfuse3.so.3", - "/usr/lib64/libfuse3.so", - "/usr/lib64/libfuse3.so.3", - "/usr/lib/x86_64-linux-gnu/libfuse3.so", - "/usr/lib/x86_64-linux-gnu/libfuse3.so.3", - nullptr}; - + // Check for FUSE. Try the dynamic loader first (resolves via the + // ld.so cache, so any SOVERSION the distro ships is picked up — Fedora + // 44+ and Arch ship libfuse3.so.4, older distros .so.3, Debian/Ubuntu + // hide the unversioned .so behind the -dev package). Fall back to a + // static path list for sandboxes that block dlopen. + static const char* fuseSonames[] = {"libfuse3.so.4", "libfuse3.so.3", + "libfuse3.so", nullptr}; bool fuseFound = false; - for (int i = 0; fusePaths[i]; ++i) { - if (QFileInfo::exists(fusePaths[i])) { + for (int i = 0; fuseSonames[i]; ++i) { + if (void* h = dlopen(fuseSonames[i], RTLD_LAZY | RTLD_NOLOAD)) { + dlclose(h); + fuseFound = true; + break; + } + if (void* h = dlopen(fuseSonames[i], RTLD_LAZY)) { + dlclose(h); fuseFound = true; break; } } + if (!fuseFound) { + static const char* fusePaths[] = { + "/usr/lib/libfuse3.so", + "/usr/lib/libfuse3.so.3", + "/usr/lib/libfuse3.so.4", + "/usr/lib64/libfuse3.so", + "/usr/lib64/libfuse3.so.3", + "/usr/lib64/libfuse3.so.4", + "/usr/lib/x86_64-linux-gnu/libfuse3.so", + "/usr/lib/x86_64-linux-gnu/libfuse3.so.3", + "/usr/lib/x86_64-linux-gnu/libfuse3.so.4", + nullptr}; + for (int i = 0; fusePaths[i]; ++i) { + if (QFileInfo::exists(fusePaths[i])) { + fuseFound = true; + break; + } + } + } if (!fuseFound) { log::warn("libfuse3 not found - FUSE VFS will not work"); ++n; -- cgit v1.3.1