mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-01-22 07:48:47 +08:00
Actively report to syslog when waiting for mounts
This commit is contained in:
parent
9744eab819
commit
eebd6e9eb4
|
@ -188,6 +188,9 @@ namespace l
|
|||
branch.set_minfreespace(minfreespace.value());
|
||||
|
||||
fs::glob(glob,&paths);
|
||||
if(paths.empty())
|
||||
paths.push_back(glob);
|
||||
|
||||
fs::realpathize(&paths);
|
||||
for(auto &path : paths)
|
||||
{
|
||||
|
|
|
@ -17,96 +17,116 @@
|
|||
*/
|
||||
|
||||
#include "fs_wait_for_mount.hpp"
|
||||
#include "syslog.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
|
||||
namespace fs
|
||||
{
|
||||
typedef std::unordered_set<fs::Path> PathSet;
|
||||
}
|
||||
|
||||
constexpr std::chrono::milliseconds SLEEP_DURATION = std::chrono::milliseconds(333);
|
||||
|
||||
|
||||
bool
|
||||
fs::wait_for_mount(const struct stat &src_st_,
|
||||
const ghc::filesystem::path &tgtpath_,
|
||||
const std::chrono::milliseconds &timeout_)
|
||||
template<>
|
||||
struct std::hash<fs::Path>
|
||||
{
|
||||
int rv;
|
||||
std::chrono::duration<double> time_diff;
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_time;
|
||||
std::size_t
|
||||
operator()(fs::Path const &path_) const noexcept
|
||||
{
|
||||
return std::hash<std::string>{}(path_.string());
|
||||
}
|
||||
};
|
||||
|
||||
start_time = std::chrono::steady_clock::now();
|
||||
while(true)
|
||||
static
|
||||
void
|
||||
_check_mounted(const struct stat &src_st_,
|
||||
const fs::PathSet &tgt_paths_,
|
||||
fs::PathVector *successes_,
|
||||
fs::PathVector *failures_)
|
||||
{
|
||||
fs::PathVector &successes = *successes_;
|
||||
fs::PathVector &failures = *failures_;
|
||||
|
||||
for(auto const &tgt_path : tgt_paths_)
|
||||
{
|
||||
int rv;
|
||||
struct stat tgt_st;
|
||||
|
||||
rv = fs::stat(tgtpath_,&tgt_st);
|
||||
rv = fs::stat(tgt_path,&tgt_st);
|
||||
if(rv == 0)
|
||||
{
|
||||
if(tgt_st.st_dev != src_st_.st_dev)
|
||||
return true;
|
||||
successes.push_back(tgt_path);
|
||||
else
|
||||
failures.push_back(tgt_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
failures.push_back(tgt_path);
|
||||
}
|
||||
|
||||
time_diff = (std::chrono::steady_clock::now() - start_time);
|
||||
if(time_diff > timeout_)
|
||||
return false;
|
||||
|
||||
std::this_thread::sleep_for(SLEEP_DURATION);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
_wait_for_mount(const struct stat &src_st_,
|
||||
const fs::PathVector &tgtpaths_,
|
||||
const std::chrono::milliseconds &timeout_,
|
||||
fs::PathVector &failed_paths_)
|
||||
const fs::PathVector &tgt_paths_,
|
||||
const std::chrono::milliseconds &timeout_)
|
||||
{
|
||||
bool rv;
|
||||
fs::PathVector::const_iterator i;
|
||||
std::chrono::milliseconds timeout;
|
||||
std::chrono::milliseconds diff;
|
||||
fs::PathVector successes;
|
||||
fs::PathVector failures;
|
||||
std::unordered_set<fs::Path> tgt_paths;
|
||||
std::chrono::time_point<std::chrono::steady_clock> now;
|
||||
std::chrono::time_point<std::chrono::steady_clock> start_time;
|
||||
std::chrono::time_point<std::chrono::steady_clock> deadline;
|
||||
|
||||
timeout = timeout_;
|
||||
now = start_time = std::chrono::steady_clock::now();
|
||||
for(auto i = tgtpaths_.begin(); i != tgtpaths_.end(); ++i)
|
||||
tgt_paths.insert(tgt_paths_.begin(),tgt_paths_.end());
|
||||
now = std::chrono::steady_clock::now();
|
||||
deadline = now + timeout_;
|
||||
|
||||
while(true)
|
||||
{
|
||||
diff = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
|
||||
timeout -= diff;
|
||||
if(tgt_paths.empty())
|
||||
break;
|
||||
if(now >= deadline)
|
||||
break;
|
||||
|
||||
rv = fs::wait_for_mount(src_st_,*i,timeout);
|
||||
if(rv == false)
|
||||
failed_paths_.push_back(*i);
|
||||
successes.clear();
|
||||
failures.clear();
|
||||
::_check_mounted(src_st_,tgt_paths,&successes,&failures);
|
||||
for(auto const &path : successes)
|
||||
{
|
||||
tgt_paths.erase(path);
|
||||
syslog_info("%s is mounted",path.string().c_str());
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(SLEEP_DURATION);
|
||||
now = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
for(auto const &path : failures)
|
||||
syslog_notice("%s not mounted within timeout",path.string().c_str());
|
||||
if(!failures.empty())
|
||||
syslog_warning("Continuing to mount mergerfs despite %u branches not "
|
||||
"being different from the mountpoint filesystem",
|
||||
failures.size());
|
||||
}
|
||||
|
||||
void
|
||||
fs::wait_for_mount(const struct stat &src_st_,
|
||||
const fs::PathVector &tgtpaths_,
|
||||
const std::chrono::milliseconds &timeout_,
|
||||
fs::PathVector &failed_paths_)
|
||||
{
|
||||
if(tgtpaths_.empty())
|
||||
return;
|
||||
|
||||
_wait_for_mount(src_st_,tgtpaths_,timeout_,failed_paths_);
|
||||
}
|
||||
|
||||
void
|
||||
fs::wait_for_mount(const ghc::filesystem::path &srcpath_,
|
||||
const fs::PathVector &tgtpaths_,
|
||||
const std::chrono::milliseconds &timeout_,
|
||||
fs::PathVector &failed_paths_)
|
||||
fs::wait_for_mount(const fs::Path &src_path_,
|
||||
const fs::PathVector &tgt_paths_,
|
||||
const std::chrono::milliseconds &timeout_)
|
||||
{
|
||||
int rv;
|
||||
struct stat src_st;
|
||||
|
||||
rv = fs::stat(srcpath_,&src_st);
|
||||
rv = fs::stat(src_path_,&src_st);
|
||||
if(rv == -1)
|
||||
return;
|
||||
return syslog_error("Error stat'ing mount path: %s (%s)",
|
||||
src_path_.c_str(),
|
||||
strerror(errno));
|
||||
|
||||
fs::wait_for_mount(src_st,tgtpaths_,timeout_,failed_paths_);
|
||||
::_wait_for_mount(src_st,tgt_paths_,timeout_);
|
||||
}
|
||||
|
|
|
@ -29,22 +29,8 @@
|
|||
|
||||
namespace fs
|
||||
{
|
||||
typedef std::vector<ghc::filesystem::path> PathVector;
|
||||
|
||||
bool
|
||||
wait_for_mount(const struct stat &st,
|
||||
const ghc::filesystem::path &tgtpath,
|
||||
void
|
||||
wait_for_mount(const fs::Path &srcpath,
|
||||
const fs::PathVector &tgtpaths,
|
||||
const std::chrono::milliseconds &timeout);
|
||||
|
||||
void
|
||||
wait_for_mount(const struct stat &st,
|
||||
const fs::PathVector &tgtpaths,
|
||||
const std::chrono::milliseconds &timeout,
|
||||
fs::PathVector &failed_paths);
|
||||
|
||||
void
|
||||
wait_for_mount(const ghc::filesystem::path &srcpath,
|
||||
const fs::PathVector &tgtpaths,
|
||||
const std::chrono::milliseconds &timeout,
|
||||
fs::PathVector &failed_paths);
|
||||
}
|
||||
|
|
|
@ -156,7 +156,6 @@ namespace l
|
|||
wait_for_mount(const Config::Read &cfg_)
|
||||
{
|
||||
fs::PathVector paths;
|
||||
fs::PathVector failed;
|
||||
std::chrono::milliseconds timeout;
|
||||
|
||||
paths = cfg_->branches->to_paths();
|
||||
|
@ -167,15 +166,7 @@ namespace l
|
|||
timeout = std::chrono::milliseconds(cfg_->branches_mount_timeout * 1000);
|
||||
fs::wait_for_mount((std::string)cfg_->mountpoint,
|
||||
paths,
|
||||
timeout,
|
||||
failed);
|
||||
for(auto &path : failed)
|
||||
syslog_warning("Branch %s was not mounted within timeout",
|
||||
path.c_str());
|
||||
if(failed.size())
|
||||
syslog_warning("Continuing to mount mergerfs despite %u branches not "
|
||||
"being different from the mountpoint filesystem",
|
||||
failed.size());
|
||||
timeout);
|
||||
}
|
||||
|
||||
static
|
||||
|
|
Loading…
Reference in New Issue
Block a user