From f0e9b4002322ada34bc76bb7de9335ed7265d67a Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Mon, 14 Dec 2020 18:18:42 +0100 Subject: [PATCH] Allow building with FUSE and FUSE3 --- CMakeLists.txt | 48 +++++++++++++++++-------------- src/dwarfs.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ad581b1b..8213e837 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,15 +85,15 @@ endif() find_package(PkgConfig REQUIRED) -if(STATIC_BUILD_DO_NOT_USE) - pkg_check_modules(FUSE REQUIRED IMPORTED_TARGET fuse>=2.9.9) -else() - pkg_check_modules(FUSE3 REQUIRED IMPORTED_TARGET fuse3>=3.4.1) -endif() - +pkg_check_modules(FUSE IMPORTED_TARGET fuse>=2.9.9) +pkg_check_modules(FUSE3 IMPORTED_TARGET fuse3>=3.4.1) pkg_check_modules(LIBLZ4 IMPORTED_TARGET liblz4>=1.8.3) pkg_check_modules(LIBLZMA IMPORTED_TARGET liblzma>=5.2.4) +if(NOT FUSE_FOUND AND NOT FUSE3_FOUND) + message(FATAL_ERROR "No FUSE or FUSE3 library found") +endif() + find_path(SPARSEHASH_INCLUDE_DIR sparsehash/dense_hash_map REQUIRED) find_program(RONN_EXE ronn) @@ -194,11 +194,30 @@ endif() add_library(dwarfs ${LIBDWARFS_SRC}) add_executable(mkdwarfs src/mkdwarfs.cpp) -add_executable(dwarfs-bin src/dwarfs.cpp) add_executable(dwarfsck src/dwarfsck.cpp) add_executable(dwarfsbench src/dwarfsbench.cpp) -list(APPEND BINARY_TARGETS mkdwarfs dwarfs-bin dwarfsck dwarfsbench) +list(APPEND BINARY_TARGETS mkdwarfs dwarfsck dwarfsbench) + +if(FUSE3_FOUND) + add_executable(dwarfs-bin src/dwarfs.cpp) + target_compile_definitions(dwarfs-bin PRIVATE _FILE_OFFSET_BITS=64 + FUSE_USE_VERSION=35) + set_target_properties(dwarfs-bin PROPERTIES OUTPUT_NAME dwarfs) + target_link_libraries(dwarfs-bin PkgConfig::FUSE3) + install(TARGETS dwarfs-bin RUNTIME DESTINATION sbin) + list(APPEND BINARY_TARGETS dwarfs-bin) +endif() + +if(FUSE_FOUND) + add_executable(dwarfs2-bin src/dwarfs.cpp) + target_compile_definitions(dwarfs2-bin PRIVATE _FILE_OFFSET_BITS=64 + FUSE_USE_VERSION=29) + set_target_properties(dwarfs2-bin PROPERTIES OUTPUT_NAME dwarfs2) + target_link_libraries(dwarfs2-bin PkgConfig::FUSE) + install(TARGETS dwarfs2-bin RUNTIME DESTINATION sbin) + list(APPEND BINARY_TARGETS dwarfs2-bin) +endif() if(WITH_TESTS) add_executable(dwarfs_test test/dwarfs.cpp test/loremipsum.cpp) @@ -355,14 +374,6 @@ foreach(tgt dwarfs ${BINARY_TARGETS}) add_dependencies(${tgt} metadata_thrift) endforeach() -target_compile_definitions(dwarfs-bin PRIVATE _FILE_OFFSET_BITS=64) - -if(STATIC_BUILD_DO_NOT_USE) - target_compile_definitions(dwarfs-bin PRIVATE FUSE_USE_VERSION=29) -else() - target_compile_definitions(dwarfs-bin PRIVATE FUSE_USE_VERSION=35) -endif() - target_link_libraries( dwarfs metadata_thrift @@ -392,8 +403,6 @@ if(WITH_PYTHON) endif() endif() -set_target_properties(dwarfs-bin PROPERTIES OUTPUT_NAME dwarfs) - add_custom_target(mount.dwarfs ALL COMMAND ${CMAKE_COMMAND} -E create_symlink dwarfs mount.dwarfs) @@ -402,8 +411,6 @@ if(STATIC_BUILD_DO_NOT_USE) set(CMAKE_CXX_LINK_EXECUTABLE "g++ -static -static-libgcc -static-libstdc++ -o -Wl,-allow-multiple-definition libdwarfs.a -Wl,-Bstatic /usr/lib/x86_64-linux-gnu/libfuse.a libmetadata_thrift.a libthrift_light.a folly/libfolly.a /usr/lib/x86_64-linux-gnu/libfmt.a /usr/lib/x86_64-linux-gnu/libboost_context.a /usr/lib/x86_64-linux-gnu/libboost_regex.a /usr/lib/x86_64-linux-gnu/libboost_thread.a /usr/lib/x86_64-linux-gnu/libboost_atomic.a /usr/lib/x86_64-linux-gnu/libdouble-conversion.a /usr/lib/x86_64-linux-gnu/libgflags.a /usr/lib/x86_64-linux-gnu/libglog.a /usr/lib/x86_64-linux-gnu/libevent.a /usr/lib/x86_64-linux-gnu/libz.a /usr/lib/x86_64-linux-gnu/libssl.a /usr/lib/x86_64-linux-gnu/libcrypto.a /usr/lib/x86_64-linux-gnu/libiberty.a /usr/lib/x86_64-linux-gnu/libiberty.a /usr/lib/x86_64-linux-gnu/libunwind.a /usr/lib/gcc/x86_64-linux-gnu/10/libatomic.a /usr/lib/x86_64-linux-gnu/libboost_date_time.a /usr/lib/x86_64-linux-gnu/libboost_filesystem.a /usr/lib/x86_64-linux-gnu/libboost_program_options.a /usr/lib/x86_64-linux-gnu/libboost_system.a zstd/build/cmake/lib/libzstd.a /usr/lib/x86_64-linux-gnu/liblz4.a /usr/lib/x86_64-linux-gnu/liblzma.a /usr/lib/x86_64-linux-gnu/libz.a /usr/lib/x86_64-linux-gnu/libpthread.a /usr/lib/x86_64-linux-gnu/libdl.a /usr/lib/x86_64-linux-gnu/libc.a /usr/lib/x86_64-linux-gnu/libm.a /usr/lib/x86_64-linux-gnu/librt.a" ) -else() - target_link_libraries(dwarfs-bin PkgConfig::FUSE3) endif() add_custom_target( @@ -418,7 +425,6 @@ install( RUNTIME DESTINATION bin LIBRARY DESTINATION lib ARCHIVE DESTINATION lib) -install(TARGETS dwarfs-bin RUNTIME DESTINATION sbin) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mount.dwarfs DESTINATION sbin) install(FILES ${MAN_PAGES} DESTINATION share/man/man1) diff --git a/src/dwarfs.cpp b/src/dwarfs.cpp index 5545ee3a..c8233f12 100644 --- a/src/dwarfs.cpp +++ b/src/dwarfs.cpp @@ -30,10 +30,11 @@ #include #include -#if DWARFS_STATIC_BUILD -#include -#else +#if FUSE_USE_VERSION >= 30 #include +#else +#include +#include #endif #include "dwarfs/error.h" @@ -425,7 +426,8 @@ void op_statfs(fuse_req_t req, fuse_ino_t /*ino*/) { } void usage(const char* progname) { - std::cerr << "dwarfs (c) Marcus Holland-Moritz\n\n" + std::cerr << "dwarfs (" << DWARFS_VERSION << ", fuse version " + << FUSE_USE_VERSION << ") (c) Marcus Holland-Moritz\n\n" << "usage: " << progname << " image mountpoint [options]\n\n" << "DWARFS options:\n" << " -o cachesize=SIZE set size of block cache (512M)\n" @@ -439,7 +441,17 @@ void usage(const char* progname) { << " -o debuglevel=NAME error, warn, (info), debug, trace\n" << std::endl; +#if FUSE_USE_VERSION >= 30 fuse_cmdline_help(); +#else + struct fuse_args args = FUSE_ARGS_INIT(0, nullptr); + fuse_opt_add_arg(&args, progname); + fuse_opt_add_arg(&args, "-ho"); + struct fuse_operations fsops; + ::memset(&fsops, 0, sizeof(fsops)); + fuse_main(args.argc, args.argv, &fsops, nullptr); + fuse_opt_free_args(&args); +#endif ::exit(1); } @@ -489,6 +501,8 @@ void init_lowlevel_ops(struct fuse_lowlevel_ops& ops) { // ops.listxattr = &op_listxattr; } +#if FUSE_USE_VERSION > 30 + int run_fuse(struct fuse_args& args, struct fuse_cmdline_opts const& fuse_opts) { struct fuse_lowlevel_ops fsops; @@ -530,6 +544,44 @@ int run_fuse(struct fuse_args& args, return err; } +#else + +int run_fuse(struct fuse_args& args, char* mountpoint, int mt, int fg) { + struct fuse_lowlevel_ops fsops; + + ::memset(&fsops, 0, sizeof(fsops)); + + if (s_opts.debuglevel >= logger::DEBUG) { + init_lowlevel_ops(fsops); + } else { + init_lowlevel_ops(fsops); + } + + int err = 1; + + if (auto ch = fuse_mount(mountpoint, &args)) { + if (auto se = fuse_lowlevel_new(&args, &fsops, sizeof(fsops), nullptr)) { + if (fuse_daemonize(fg) != -1) { + if (fuse_set_signal_handlers(se) != -1) { + fuse_session_add_chan(se, ch); + err = mt ? fuse_session_loop_mt(se) : fuse_session_loop(se); + fuse_remove_signal_handlers(se); + fuse_session_remove_chan(ch); + } + } + fuse_session_destroy(se); + } + fuse_unmount(mountpoint, ch); + } + + ::free(mountpoint); + fuse_opt_free_args(&args); + + return err; +} + +#endif + } // namespace dwarfs int main(int argc, char* argv[]) { @@ -543,6 +595,7 @@ int main(int argc, char* argv[]) { fuse_opt_parse(&args, &s_opts, dwarfs_opts, option_hdl); +#if FUSE_USE_VERSION >= 30 struct fuse_cmdline_opts fuse_opts; if (fuse_parse_cmdline(&args, &fuse_opts) == -1 || !fuse_opts.mountpoint) { @@ -552,6 +605,18 @@ int main(int argc, char* argv[]) { if (fuse_opts.foreground) { folly::symbolizer::installFatalSignalHandler(); } +#else + char* mountpoint = nullptr; + int mt, fg; + + if (fuse_parse_cmdline(&args, &mountpoint, &mt, &fg) == -1 || !mountpoint) { + usage(s_opts.progname); + } + + if (fg) { + folly::symbolizer::installFatalSignalHandler(); + } +#endif // TODO: foreground mode, stderr vs. syslog? s_opts.debuglevel = s_opts.debuglevel_str @@ -582,5 +647,9 @@ int main(int argc, char* argv[]) { metadata_v2::get_stat_defaults(&s_opts.stat_defaults); +#if FUSE_USE_VERSION >= 30 return run_fuse(args, fuse_opts); +#else + return run_fuse(args, mountpoint, mt, fg); +#endif }