From 9adddfc66d76d0a5f253fb604bc04c6380894a80 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Wed, 1 Feb 2023 23:05:45 -0500 Subject: [PATCH] Add option to lazy umount target mount point --- libfuse/lib/fuse_msgbuf.cpp | 2 +- src/config.cpp | 6 +++-- src/config.hpp | 3 ++- src/fs_umount2.hpp | 49 +++++++++++++++++++++++++++++++++++++ src/fuse_link.cpp | 2 +- src/fuse_rename.cpp | 2 +- src/mergerfs.cpp | 32 +++++++++++++++++++++++- src/option_parser.cpp | 4 +-- src/syslog.cpp | 11 +++++++++ src/syslog.hpp | 1 + 10 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 src/fs_umount2.hpp diff --git a/libfuse/lib/fuse_msgbuf.cpp b/libfuse/lib/fuse_msgbuf.cpp index 0c29bc94..45861906 100644 --- a/libfuse/lib/fuse_msgbuf.cpp +++ b/libfuse/lib/fuse_msgbuf.cpp @@ -2,7 +2,6 @@ ISC License Copyright (c) 2022, Antonio SJ Musumeci - Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. @@ -22,6 +21,7 @@ #include #include +#include #include #include diff --git a/src/config.cpp b/src/config.cpp index 2825a82b..e00478d9 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -92,10 +92,11 @@ Config::Config() fuse_msg_size(FUSE_MAX_MAX_PAGES), ignorepponrename(false), inodecalc("hybrid-hash"), + lazy_umount_mountpoint(false), link_cow(false), link_exdev(LinkEXDEV::ENUM::PASSTHROUGH), log_metrics(false), - mount(), + mountpoint(), moveonenospc(false), nfsopenhack(NFSOpenHack::ENUM::OFF), nullrw(false), @@ -160,11 +161,12 @@ Config::Config() _map["ignorepponrename"] = &ignorepponrename; _map["inodecalc"] = &inodecalc; _map["kernel_cache"] = &kernel_cache; + _map["lazy-umount-mountpoint"] = &lazy_umount_mountpoint; _map["link_cow"] = &link_cow; _map["link-exdev"] = &link_exdev; _map["log.metrics"] = &log_metrics; _map["minfreespace"] = &minfreespace; - _map["mount"] = &mount; + _map["mount"] = &mountpoint; _map["moveonenospc"] = &moveonenospc; _map["nfsopenhack"] = &nfsopenhack; _map["nullrw"] = &nullrw; diff --git a/src/config.hpp b/src/config.hpp index d113a21e..05e2f3ad 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -121,10 +121,11 @@ public: ConfigBOOL ignorepponrename; InodeCalc inodecalc; ConfigBOOL kernel_cache; + ConfigBOOL lazy_umount_mountpoint; ConfigBOOL link_cow; LinkEXDEV link_exdev; LogMetrics log_metrics; - ConfigSTR mount; + ConfigSTR mountpoint; MoveOnENOSPC moveonenospc; NFSOpenHack nfsopenhack; ConfigBOOL nullrw; diff --git a/src/fs_umount2.hpp b/src/fs_umount2.hpp new file mode 100644 index 00000000..7fc1c2c2 --- /dev/null +++ b/src/fs_umount2.hpp @@ -0,0 +1,49 @@ +/* + ISC License + + Copyright (c) 2023, Antonio SJ Musumeci + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#pragma once + +#include +#include + +#include + +namespace fs +{ + static + inline + int + umount2(const std::string target_, + const int flags_) + { + int rv; + + rv = ::umount2(target_.c_str(), + flags_); + + return ((rv == -1) ? -errno : rv); + } + + static + inline + int + umount_lazy(const std::string target_) + { + return fs::umount2(target_,MNT_DETACH); + } +} diff --git a/src/fuse_link.cpp b/src/fuse_link.cpp index 7547b264..754228ce 100644 --- a/src/fuse_link.cpp +++ b/src/fuse_link.cpp @@ -326,7 +326,7 @@ namespace l st_, timeouts_); case LinkEXDEV::ENUM::ABS_POOL_SYMLINK: - return l::link_exdev_abs_pool_symlink(cfg_->mount, + return l::link_exdev_abs_pool_symlink(cfg_->mountpoint, oldpath_, newpath_, st_, diff --git a/src/fuse_rename.cpp b/src/fuse_rename.cpp index ee2384e8..c112ef99 100644 --- a/src/fuse_rename.cpp +++ b/src/fuse_rename.cpp @@ -358,7 +358,7 @@ namespace l case RenameEXDEV::ENUM::ABS_SYMLINK: return l::rename_exdev_abs_symlink(cfg_->func.rename.policy, cfg_->branches, - cfg_->mount, + cfg_->mountpoint, oldfusepath_, newfusepath_); } diff --git a/src/mergerfs.cpp b/src/mergerfs.cpp index eb84bc3a..28473060 100644 --- a/src/mergerfs.cpp +++ b/src/mergerfs.cpp @@ -18,6 +18,7 @@ #include "syslog.hpp" #include "fs_path.hpp" +#include "fs_umount2.hpp" #include "mergerfs.hpp" #include "option_parser.hpp" #include "resources.hpp" @@ -162,7 +163,7 @@ namespace l (uint64_t)cfg_->branches_mount_timeout); timeout = std::chrono::milliseconds(cfg_->branches_mount_timeout * 1000); - fs::wait_for_mount((std::string)cfg_->mount, + fs::wait_for_mount((std::string)cfg_->mountpoint, paths, timeout, failed); @@ -175,6 +176,32 @@ namespace l failed.size()); } + static + void + lazy_umount(const std::string target_) + { + int rv; + + rv = fs::umount_lazy(target_); + switch(rv) + { + case 0: + syslog_notice("%s has been successfully lazily unmounted", + target_.c_str()); + break; + case -EINVAL: + syslog_notice("%s was not a mount point needing to be unmounted", + target_.c_str()); + break; + default: + syslog_error("Error unmounting %s: %d - %s", + target_.c_str(), + -rv, + strerror(-rv)); + break; + } + } + int main(const int argc_, char **argv_) @@ -205,6 +232,9 @@ namespace l l::setup_resources(cfg->scheduling_priority); l::get_fuse_operations(ops,cfg->nullrw); + if(cfg->lazy_umount_mountpoint) + l::lazy_umount(cfg->mountpoint); + return fuse_main(args.argc, args.argv, &ops); diff --git a/src/option_parser.cpp b/src/option_parser.cpp index 41b04dc6..962a573d 100644 --- a/src/option_parser.cpp +++ b/src/option_parser.cpp @@ -378,7 +378,7 @@ check_for_mount_loop(Config::Write &cfg_, fs::PathVector branches; std::error_code ec; - mount = (std::string)cfg_->mount; + mount = (std::string)cfg_->mountpoint; branches = cfg_->branches->to_paths(); for(const auto &branch : branches) { @@ -416,7 +416,7 @@ namespace options if(cfg->branches->empty()) errs_->push_back({0,"branches not set"}); - if(cfg->mount->empty()) + if(cfg->mountpoint->empty()) errs_->push_back({0,"mountpoint not set"}); check_for_mount_loop(cfg,errs_); diff --git a/src/syslog.cpp b/src/syslog.cpp index d6fe100c..7e994086 100644 --- a/src/syslog.cpp +++ b/src/syslog.cpp @@ -73,6 +73,17 @@ syslog_info(const char *format_, va_end(valist); } +void +syslog_notice(const char *format_, + ...) +{ + va_list valist; + + va_start(valist,format_); + syslog_log(LOG_NOTICE,format_,valist); + va_end(valist); +} + void syslog_warning(const char *format_, ...) diff --git a/src/syslog.hpp b/src/syslog.hpp index f9df4f51..a617ad39 100644 --- a/src/syslog.hpp +++ b/src/syslog.hpp @@ -24,6 +24,7 @@ void syslog_open(); void syslog_log(const int priority, const char *format, ...); void syslog_info(const char *format, ...); +void syslog_notice(const char *format, ...); void syslog_warning(const char *format, ...); void syslog_error(const char *format, ...); void syslog_close();