From d8691d282b5049fdf06fb0d9662b35ce27822ff6 Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Sat, 22 Dec 2018 02:26:38 +0100 Subject: [PATCH] Defer daemonization to Fuse, introduce Fuse::runInBackground() / Fuse::runInForeground() --- src/cryfs-cli/Cli.cpp | 10 ++++++--- src/cryfs-cli/program_options/Parser.cpp | 3 --- src/fspp/fuse/Fuse.cpp | 28 +++++++++++++++++++++++- src/fspp/fuse/Fuse.h | 5 ++++- test/fspp/testutils/FuseTest.cpp | 2 +- test/fspp/testutils/FuseThread.cpp | 2 +- 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/cryfs-cli/Cli.cpp b/src/cryfs-cli/Cli.cpp index 4c5ca4c6..be5733bf 100644 --- a/src/cryfs-cli/Cli.cpp +++ b/src/cryfs-cli/Cli.cpp @@ -268,11 +268,15 @@ namespace cryfs { std::cout << "\nMounting filesystem. To unmount, call:\n$ fusermount -u " << options.mountDir() << "\n" << std::endl; #endif - fuse->run(options.mountDir(), options.fuseOptions()); + if (options.foreground()) { + fuse->runInForeground(options.mountDir(), options.fuseOptions()); + } else { + fuse->runInBackground(options.mountDir(), options.fuseOptions()); + } - if (stoppedBecauseOfIntegrityViolation) { + if (stoppedBecauseOfIntegrityViolation) { throw CryfsException("Integrity violation detected. Unmounting.", ErrorCode::IntegrityViolation); - } + } } catch (const CryfsException &e) { throw; // CryfsException is only thrown if setup goes wrong. Throw it through so that we get the correct process exit code. } catch (const std::exception &e) { diff --git a/src/cryfs-cli/program_options/Parser.cpp b/src/cryfs-cli/program_options/Parser.cpp index 89a6042f..a7298393 100644 --- a/src/cryfs-cli/program_options/Parser.cpp +++ b/src/cryfs-cli/program_options/Parser.cpp @@ -56,9 +56,6 @@ ProgramOptions Parser::parse(const vector &supportedCiphers) const { configfile = bf::absolute(vm["config"].as()); } bool foreground = vm.count("foreground"); - if (foreground) { - fuseOptions.push_back(const_cast("-f")); - } bool allowFilesystemUpgrade = vm.count("allow-filesystem-upgrade"); bool allowReplacedFilesystem = vm.count("allow-replaced-filesystem"); optional unmountAfterIdleMinutes = 0.0; // first setting to 0 and then to none is somehow needed to silence a GCC warning from -Wmaybe-uninitialized diff --git a/src/fspp/fuse/Fuse.cpp b/src/fspp/fuse/Fuse.cpp index 00528318..e2108580 100644 --- a/src/fspp/fuse/Fuse.cpp +++ b/src/fspp/fuse/Fuse.cpp @@ -243,7 +243,33 @@ void Fuse::_logUnknownException() { LOG(ERR, "Unknown exception thrown"); } -void Fuse::run(const bf::path &mountdir, const vector &fuseOptions) { +void Fuse::runInForeground(const bf::path &mountdir, const vector &fuseOptions) { + vector realFuseOptions = fuseOptions; + if (std::find(realFuseOptions.begin(), realFuseOptions.end(), "-f") == realFuseOptions.end()) { + realFuseOptions.push_back("-f"); + } + _run(mountdir, realFuseOptions); +} + +void Fuse::runInBackground(const bf::path &mountdir, const vector &fuseOptions) { + vector realFuseOptions = fuseOptions; + _removeAndWarnIfExists(&realFuseOptions, "-f"); + _removeAndWarnIfExists(&realFuseOptions, "-d"); + _run(mountdir, realFuseOptions); +} + +void Fuse::_removeAndWarnIfExists(vector *fuseOptions, const std::string &option) { + auto found = std::find(fuseOptions->begin(), fuseOptions->end(), option); + if (found != fuseOptions->end()) { + LOG(WARN, "The fuse option {} only works when running in foreground. Removing fuse option.", option); + do { + fuseOptions->erase(found); + found = std::find(fuseOptions->begin(), fuseOptions->end(), option); + } while (found != fuseOptions->end()); + } +} + +void Fuse::_run(const bf::path &mountdir, const vector &fuseOptions) { _mountdir = mountdir; ASSERT(_argv.size() == 0, "Filesystem already started"); diff --git a/src/fspp/fuse/Fuse.h b/src/fspp/fuse/Fuse.h index 7d173654..a9cead1c 100644 --- a/src/fspp/fuse/Fuse.h +++ b/src/fspp/fuse/Fuse.h @@ -24,7 +24,8 @@ public: explicit Fuse(std::function (Fuse *fuse)> init, std::function onMounted, std::string fstype, boost::optional fsname); ~Fuse(); - void run(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); + void runInBackground(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); + void runInForeground(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); bool running() const; void stop(); @@ -63,6 +64,8 @@ private: static void _logException(const std::exception &e); static void _logUnknownException(); static char *_create_c_string(const std::string &str); + static void _removeAndWarnIfExists(std::vector *fuseOptions, const std::string &option); + void _run(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); static bool _has_option(const std::vector &vec, const std::string &key); static bool _has_entry_with_prefix(const std::string &prefix, const std::vector &vec); std::vector _build_argv(const boost::filesystem::path &mountdir, const std::vector &fuseOptions); diff --git a/test/fspp/testutils/FuseTest.cpp b/test/fspp/testutils/FuseTest.cpp index 62cfa419..55a27f45 100644 --- a/test/fspp/testutils/FuseTest.cpp +++ b/test/fspp/testutils/FuseTest.cpp @@ -59,7 +59,7 @@ FuseTest::TempTestFS::TempTestFS(shared_ptr fsimpl) :_mountDir(), _fuse([fsimpl] (Fuse*) {return fsimpl;}, []{}, "fusetest", boost::none), _fuse_thread(&_fuse) { - _fuse_thread.start(_mountDir.path(), {"-f"}); + _fuse_thread.start(_mountDir.path(), {}); } FuseTest::TempTestFS::~TempTestFS() { diff --git a/test/fspp/testutils/FuseThread.cpp b/test/fspp/testutils/FuseThread.cpp index b73df2f4..8da58591 100644 --- a/test/fspp/testutils/FuseThread.cpp +++ b/test/fspp/testutils/FuseThread.cpp @@ -18,7 +18,7 @@ FuseThread::FuseThread(Fuse *fuse) void FuseThread::start(const bf::path &mountDir, const vector &fuseOptions) { _child = thread([this, mountDir, fuseOptions] () { - _fuse->run(mountDir, fuseOptions); + _fuse->runInForeground(mountDir, fuseOptions); }); //Wait until it is running (busy waiting is simple and doesn't hurt much here) while(!_fuse->running()) {}