From b603d3b58a044243abdd04174029e0cf881d5fdc Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Fri, 10 Jul 2020 17:30:07 -0700 Subject: [PATCH] Add an --immediate flag to cryfs-unmount that tries to unmount immediately and doesn't wait for processes to release their locks on the file system. --- ChangeLog.txt | 1 + src/cryfs-unmount/Cli.cpp | 27 ++++++++++++++++--- src/cryfs-unmount/program_options/Parser.cpp | 6 +++-- .../program_options/ProgramOptions.cpp | 21 ++++++++++----- .../program_options/ProgramOptions.h | 17 +++++++----- 5 files changed, 55 insertions(+), 17 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 6ea75bc8..faa7aa94 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -9,6 +9,7 @@ Other changes: New features: * Add support for atime mount options (noatime, strictatime, relatime, atime, nodiratime). As before, relatime is the default. +* Add an --immediate flag to cryfs-unmount that tries to unmount immediately and doesn't wait for processes to release their locks on the file system. Version 0.10.3 (unreleased) diff --git a/src/cryfs-unmount/Cli.cpp b/src/cryfs-unmount/Cli.cpp index ce6cbe7b..5832966c 100644 --- a/src/cryfs-unmount/Cli.cpp +++ b/src/cryfs-unmount/Cli.cpp @@ -25,12 +25,33 @@ void Cli::main(int argc, const char **argv) { if (!boost::filesystem::exists(options.mountDir())) { throw cryfs::CryfsException("Given mountdir doesn't exist", cryfs::ErrorCode::InaccessibleMountDir); } + + bool immediate = options.immediate(); +#if defined(__APPLE__) + if (options.immediate()) { + std::cerr << "Warning: OSX doesn't support the --immediate flag. Ignoring it."; + immediate = false; + } +#elif defined(_MSC_VER) + if (options.immediate()) { + std::cerr << "Warning: Windows doesn't support the --immediate flag. Ignoring it."; + immediate = false; + } +#endif + // TODO This doesn't seem to work with relative paths std::cout << "Unmounting CryFS filesystem at " << options.mountDir() << "." << std::endl; - Fuse::unmount(options.mountDir()); + if (immediate) { + Fuse::unmount(options.mountDir(), true); - // TODO Wait until it is actually unmounted and then show a better success message? - std::cout << "Filesystem is unmounting now." << std::endl; + // TODO Wait until it is actually unmounted and then show a better success message? + std::cout << "Filesystem is unmounting." << std::endl; + } else { + Fuse::unmount(options.mountDir(), false); + + // TODO Wait until it is actually unmounted and then show a better success message? + std::cout << "Filesystem will unmount as soon as nothing is accessing it anymore." << std::endl; + } } } diff --git a/src/cryfs-unmount/program_options/Parser.cpp b/src/cryfs-unmount/program_options/Parser.cpp index ceb05ba1..d2613114 100644 --- a/src/cryfs-unmount/program_options/Parser.cpp +++ b/src/cryfs-unmount/program_options/Parser.cpp @@ -36,8 +36,9 @@ ProgramOptions Parser::parse() const { _showHelpAndExit("Please specify a mount directory.", ErrorCode::InvalidArguments); } bf::path mountDir = vm["mount-dir"].as(); + bool immediate = vm.count("immediate"); - return ProgramOptions(std::move(mountDir)); + return ProgramOptions(std::move(mountDir), immediate); } po::variables_map Parser::_parseOptionsOrShowHelp(const vector &options) { @@ -95,8 +96,9 @@ void Parser::_addAllowedOptions(po::options_description *desc) { string blocksize_description = "The block size used when storing ciphertext blocks (in bytes). Default: "; blocksize_description += std::to_string(CryConfigConsole::DEFAULT_BLOCKSIZE_BYTES); options.add_options() + ("immediate", "unmount immediately without waiting for processes that currently access the file system to finish their file system operations. With this flag, unmounting can fail if there's processes having a lock on the file system.") ("help,h", "show help message") - ("version", "Show CryFS version number") + ("version", "show CryFS version number") ; desc->add(options); } diff --git a/src/cryfs-unmount/program_options/ProgramOptions.cpp b/src/cryfs-unmount/program_options/ProgramOptions.cpp index 4fa22740..577bdb05 100644 --- a/src/cryfs-unmount/program_options/ProgramOptions.cpp +++ b/src/cryfs-unmount/program_options/ProgramOptions.cpp @@ -7,19 +7,28 @@ using namespace cryfs_unmount::program_options; using std::string; namespace bf = boost::filesystem; -ProgramOptions::ProgramOptions(bf::path mountDir) - :_mountDir(std::move(mountDir)), - _mountDirIsDriveLetter(cpputils::path_is_just_drive_letter(_mountDir)) +ProgramOptions::ProgramOptions(bf::path mountDir, bool immediate) + : _mountDir(std::move(mountDir)), + _mountDirIsDriveLetter(cpputils::path_is_just_drive_letter(_mountDir)), + _immediate(immediate) { - if (!_mountDirIsDriveLetter) { + if (!_mountDirIsDriveLetter) + { _mountDir = bf::absolute(std::move(_mountDir)); } } -const bf::path &ProgramOptions::mountDir() const { +const bf::path &ProgramOptions::mountDir() const +{ return _mountDir; } -bool ProgramOptions::mountDirIsDriveLetter() const { +bool ProgramOptions::mountDirIsDriveLetter() const +{ return _mountDirIsDriveLetter; } + +bool ProgramOptions::immediate() const +{ + return _immediate; +} diff --git a/src/cryfs-unmount/program_options/ProgramOptions.h b/src/cryfs-unmount/program_options/ProgramOptions.h index 08f83ab2..8ab1be78 100644 --- a/src/cryfs-unmount/program_options/ProgramOptions.h +++ b/src/cryfs-unmount/program_options/ProgramOptions.h @@ -8,23 +8,28 @@ #include #include -namespace cryfs_unmount { - namespace program_options { - class ProgramOptions final { +namespace cryfs_unmount +{ + namespace program_options + { + class ProgramOptions final + { public: - ProgramOptions(boost::filesystem::path mountDir); + ProgramOptions(boost::filesystem::path mountDir, bool immediate); ProgramOptions(ProgramOptions &&rhs) = default; const boost::filesystem::path &mountDir() const; bool mountDirIsDriveLetter() const; + bool immediate() const; private: boost::filesystem::path _mountDir; bool _mountDirIsDriveLetter; + bool _immediate; DISALLOW_COPY_AND_ASSIGN(ProgramOptions); }; - } -} + } // namespace program_options +} // namespace cryfs_unmount #endif