From baec63017990759664ae508e0b9ce342f22fc918 Mon Sep 17 00:00:00 2001 From: Pavel Siska Date: Mon, 15 Jul 2024 20:26:25 +0200 Subject: [PATCH] appfs - use fusermount3 to unmount the mountPoint fusermount3 can unmount mountPoint without root priveleges. fusermount3 is called using std::system function. --- src/appFs/appFs.cpp | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/appFs/appFs.cpp b/src/appFs/appFs.cpp index 6530df6..9705a8e 100644 --- a/src/appFs/appFs.cpp +++ b/src/appFs/appFs.cpp @@ -8,11 +8,10 @@ #include +#include #include #include #include -#include -#include #include #include @@ -356,6 +355,23 @@ static void createDirectories(const std::string& path) } } +static void fuserUnmount(const std::string& mountPoint) +{ + // NOLINTBEGIN (concurrency-mt-unsafe, std::system function is not thread safe) + const std::string whichCommand = "which fusermount3 > /dev/null 2>&1"; + const int ret = std::system(whichCommand.c_str()); + if (ret != 0) { + std::cerr << "fusermount3 is not found. Unable to unmount '" + mountPoint << "'\n"; + return; + } + + const std::string fusermountCommand = "fusermount3 -u " + mountPoint; + if (std::system(fusermountCommand.c_str()) != 0) { + throw std::runtime_error(fusermountCommand + " has failed."); + } + // NOLINTEND +} + class FuseArgs { public: FuseArgs() @@ -389,22 +405,17 @@ AppFsFuse::AppFsFuse( setFuseOperations(&fuseOps); /** - * If tryToUnmountOnStart is true, this code attempts to unmount the specified mount point. - * This is necessary because if the application terminates unexpectedly, the filesystem - * might remain mounted, which can prevent proper status checking and cause subsequent - * attempts to mount it to fail. By forcing an unmount here, we ensure the mount point is - * in a clean state before proceeding. If the unmount fails, an exception is thrown to - * indicate that the cleanup process was unsuccessful. + * If tryToUnmountOnStart is true, this code attempts to unmount the specified mount point using + * fusermount3 binary. This is necessary because if the application terminates unexpectedly, the + * filesystem might remain mounted, which can prevent proper status checking and cause + * subsequent attempts to mount it to fail. By forcing an unmount here, we ensure the mount + * point is in a clean state before proceeding. */ if (tryToUnmountOnStart) { - const int ret = umount2(mountPoint.c_str(), MNT_FORCE | UMOUNT_NOFOLLOW); - if (ret < 0 && errno != ENOENT) { // ENOENT means that No such directory exists - throw std::runtime_error( - "umount of " + mountPoint + " has failed. Error: " + std::to_string(errno)); - } + fuserUnmount(mountPoint); } - if (createMountPoint) { + if (!createMountPoint) { createDirectories(mountPoint); }