From df7403c256084a620d47f5f550544f8e0f0fabf6 Mon Sep 17 00:00:00 2001 From: Ben RUBSON Date: Tue, 10 Apr 2018 10:58:08 +0200 Subject: [PATCH] Unmount improvements (#507) Log OSX unmount system error Better handle Cygwin unmount child Use WinFsp expected INT signal --- encfs/FileUtils.cpp | 27 +++++++++++++++++++-------- encfs/main.cpp | 17 ++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/encfs/FileUtils.cpp b/encfs/FileUtils.cpp index ca3db78..81ab8f4 100644 --- a/encfs/FileUtils.cpp +++ b/encfs/FileUtils.cpp @@ -1733,19 +1733,30 @@ RootPtr initFS(EncFS_Context *ctx, const std::shared_ptr &opts) { } void unmountFS(const char *mountPoint) { - // fuse_unmount succeeds and returns void + // fuse_unmount returns void, is assumed to succeed fuse_unmount(mountPoint, nullptr); #ifdef __APPLE__ // fuse_unmount does not work on Mac OS, see #428 - unmount(mountPoint, MNT_FORCE); + // However it makes encfs to hang, so we must unmount + if (unmount(mountPoint, MNT_FORCE) != 0) { + int eno = errno; + if (eno != EINVAL) { //[EINVAL] The requested directory is not in the mount table. + RLOG(ERROR) << "Filesystem unmount failed: " << strerror(eno); + } + } #endif #ifdef __CYGWIN__ - if(fork() == 0) - { - execl("/usr/bin/pkill", "/usr/bin/pkill", "-f", string("(^|/)encfs .*/.* ").append(mountPoint).append("?( |$)").c_str(), (char *)0); - } + pid_t pid; int status; - wait(&status); + if ((pid = fork()) == 0) { + execl("/usr/bin/pkill", "/usr/bin/pkill", "-INT", "-f", string("(^|/)encfs .*/.* ").append(mountPoint).append("?( |$)").c_str(), (char *)0); + int eno = errno; + RLOG(ERROR) << "Filesystem unmount failed: " << strerror(eno); + _Exit(127); + } + if (pid > 0) { + waitpid(pid, &status, 0); + } #endif } @@ -1770,8 +1781,8 @@ bool unmountFS(EncFS_Context *ctx) { return false; } // Time to unmount! + RLOG(INFO) << "Filesystem inactive, unmounting: " << ctx->opts->mountPoint; unmountFS(ctx->opts->mountPoint.c_str()); - RLOG(INFO) << "Filesystem inactive, unmounted: " << ctx->opts->mountPoint; return true; } diff --git a/encfs/main.cpp b/encfs/main.cpp index 9d40441..b0a46db 100644 --- a/encfs/main.cpp +++ b/encfs/main.cpp @@ -323,6 +323,8 @@ static bool processArgs(int argc, char *argv[], out->opts->config.assign(optarg); break; case 'u': + //we want to log to console, not to syslog, in case of error + out->isDaemon = false; out->opts->unmount = true; break; case 'f': @@ -656,16 +658,17 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - // Let's unmount if requested - if (encfsArgs->opts->unmount) { - unmountFS(encfsArgs->opts->mountPoint.c_str()); - cout << "Filesystem unmounting: " << encfsArgs->opts->mountPoint << endl; - return 0; - } - encfs::initLogging(encfsArgs->isVerbose, encfsArgs->isDaemon); ELPP_INITIALIZE_SYSLOG(encfsArgs->syslogTag.c_str(), LOG_PID, LOG_USER); + // Let's unmount if requested + if (encfsArgs->opts->unmount) { + // We use cout here to avoid logging to stderr (and to mess-up tests output) + cout << "Filesystem unmounting: " << encfsArgs->opts->mountPoint << endl; + unmountFS(encfsArgs->opts->mountPoint.c_str()); + return 0; + } + VLOG(1) << "Root directory: " << encfsArgs->opts->rootDir; VLOG(1) << "Fuse arguments: " << encfsArgs->toString();