|
|
|
@ -45,11 +45,42 @@ constexpr static const char CACHE_FILES_PROCESS_NAMES_DEFAULT[] = |
|
|
|
|
|
|
|
Config cfg; |
|
|
|
|
|
|
|
Config::CfgConfigFile::CfgConfigFile() |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
Config::CfgConfigFile::from_string(const std::string_view s_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
fs::path cfg_file; |
|
|
|
|
|
|
|
if(_depth > 5) |
|
|
|
return -ELOOP; |
|
|
|
_depth++; |
|
|
|
|
|
|
|
cfg_file = (s_.empty() ? _cfg_file : s_); |
|
|
|
|
|
|
|
rv = cfg.from_file(cfg_file); |
|
|
|
if(rv == 0) |
|
|
|
_cfg_file = cfg_file; |
|
|
|
|
|
|
|
_depth--; |
|
|
|
|
|
|
|
return rv; |
|
|
|
} |
|
|
|
|
|
|
|
std::string |
|
|
|
Config::CfgConfigFile::to_string() const |
|
|
|
{ |
|
|
|
return _cfg_file; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Config::Config() |
|
|
|
: |
|
|
|
allow_idmap(false), |
|
|
|
async_read(true), |
|
|
|
auto_cache(false), |
|
|
|
branches(minfreespace), |
|
|
|
branches_mount_timeout(0), |
|
|
|
branches_mount_timeout_fail(false), |
|
|
|
@ -63,9 +94,9 @@ Config::Config() |
|
|
|
cache_symlinks(false), |
|
|
|
cache_writeback(false), |
|
|
|
category(func), |
|
|
|
config_file(), |
|
|
|
congestion_threshold(fuse_cfg.congestion_threshold,0), |
|
|
|
debug(fuse_cfg.debug,false), |
|
|
|
direct_io(false), |
|
|
|
direct_io_allow_mmap(true), |
|
|
|
dropcacheonclose(false), |
|
|
|
export_support(true), |
|
|
|
@ -81,7 +112,6 @@ Config::Config() |
|
|
|
handle_killpriv_v2(true), |
|
|
|
ignorepponrename(false), |
|
|
|
inodecalc("hybrid-hash"), |
|
|
|
kernel_cache(false), |
|
|
|
kernel_permissions_check(true), |
|
|
|
lazy_umount_mountpoint(false), |
|
|
|
link_cow(false), |
|
|
|
@ -92,6 +122,7 @@ Config::Config() |
|
|
|
mountpoint(), |
|
|
|
moveonenospc(true), |
|
|
|
nfsopenhack(NFSOpenHack::ENUM::OFF), |
|
|
|
noforget(), |
|
|
|
nullrw(false), |
|
|
|
parallel_direct_writes(true), |
|
|
|
passthrough(Passthrough::ENUM::OFF), |
|
|
|
@ -104,7 +135,6 @@ Config::Config() |
|
|
|
read_thread_count(fuse_cfg.read_thread_count,0), |
|
|
|
readahead(0), |
|
|
|
readdir("seq"), |
|
|
|
readdirplus(false), |
|
|
|
remember_nodes(fuse_cfg.remember_nodes,0), |
|
|
|
rename_exdev(RenameEXDEV::ENUM::PASSTHROUGH), |
|
|
|
scheduling_priority(-10), |
|
|
|
@ -147,128 +177,119 @@ Config::Config() |
|
|
|
srcmounts.ro = |
|
|
|
version.ro = |
|
|
|
true; |
|
|
|
auto_cache.display = |
|
|
|
congestion_threshold.ro = |
|
|
|
direct_io.display = |
|
|
|
congestion_threshold.ro = |
|
|
|
gid.display = |
|
|
|
kernel_cache.display = |
|
|
|
max_background.ro = |
|
|
|
readdirplus.display = |
|
|
|
threads.display = |
|
|
|
uid.display = |
|
|
|
umask.display = |
|
|
|
false; |
|
|
|
|
|
|
|
_map["allow-idmap"] = &allow_idmap; |
|
|
|
_map["async_read"] = &async_read; |
|
|
|
_map["auto_cache"] = &auto_cache; |
|
|
|
_map["branches"] = &branches; |
|
|
|
_map["branches-mount-timeout"] = &branches_mount_timeout; |
|
|
|
_map["allow-idmap"] = &allow_idmap; |
|
|
|
_map["async_read"] = &async_read; |
|
|
|
_map["atomic_o_trunc"] = &_dummy; |
|
|
|
_map["auto_cache"] = &_dummy; |
|
|
|
_map["big_writes"] = &_dummy; |
|
|
|
_map["branches"] = &branches; |
|
|
|
_map["branches-mount-timeout"] = &branches_mount_timeout; |
|
|
|
_map["branches-mount-timeout-fail"] = &branches_mount_timeout_fail; |
|
|
|
_map["cache.attr"] = &cache_attr; |
|
|
|
_map["cache.entry"] = &cache_entry; |
|
|
|
_map["cache.files"] = &cache_files; |
|
|
|
_map["cache.files.process-names"] = &cache_files_process_names; |
|
|
|
_map["cache.negative_entry"] = &cache_negative_entry; |
|
|
|
_map["cache.readdir"] = &cache_readdir; |
|
|
|
_map["cache.statfs"] = &cache_statfs; |
|
|
|
_map["cache.symlinks"] = &cache_symlinks; |
|
|
|
_map["cache.writeback"] = &cache_writeback; |
|
|
|
_map["category.action"] = &category.action; |
|
|
|
_map["category.create"] = &category.create; |
|
|
|
_map["category.search"] = &category.search; |
|
|
|
_map["debug"] = &debug; |
|
|
|
_map["direct-io-allow-mmap"] = &direct_io_allow_mmap; |
|
|
|
_map["direct_io"] = &direct_io; |
|
|
|
_map["dropcacheonclose"] = &dropcacheonclose; |
|
|
|
_map["export-support"] = &export_support; |
|
|
|
_map["flush-on-close"] = &flushonclose; |
|
|
|
_map["follow-symlinks"] = &follow_symlinks; |
|
|
|
_map["fsname"] = &fsname; |
|
|
|
_map["func.access"] = &func.access; |
|
|
|
_map["func.chmod"] = &func.chmod; |
|
|
|
_map["func.chown"] = &func.chown; |
|
|
|
_map["func.create"] = &func.create; |
|
|
|
_map["func.getattr"] = &func.getattr; |
|
|
|
_map["func.getxattr"] = &func.getxattr; |
|
|
|
_map["func.link"] = &func.link; |
|
|
|
_map["func.listxattr"] = &func.listxattr; |
|
|
|
_map["func.mkdir"] = &func.mkdir; |
|
|
|
_map["func.mknod"] = &func.mknod; |
|
|
|
_map["func.open"] = &func.open; |
|
|
|
_map["func.readdir"] = &readdir; |
|
|
|
_map["func.readlink"] = &func.readlink; |
|
|
|
_map["func.removexattr"] = &func.removexattr; |
|
|
|
_map["func.rename"] = &func.rename; |
|
|
|
_map["func.rmdir"] = &func.rmdir; |
|
|
|
_map["func.setxattr"] = &func.setxattr; |
|
|
|
_map["func.symlink"] = &func.symlink; |
|
|
|
_map["func.truncate"] = &func.truncate; |
|
|
|
_map["func.unlink"] = &func.unlink; |
|
|
|
_map["func.utimens"] = &func.utimens; |
|
|
|
_map["fuse_msg_size"] = &fuse_msg_size; |
|
|
|
_map["gid"] = &gid; |
|
|
|
_map["gid-cache-expire-timeout"] = &gid_cache_expire_timeout; |
|
|
|
_map["gid-cache-remove-timeout"] = &gid_cache_remove_timeout; |
|
|
|
_map["handle-killpriv"] = &handle_killpriv; |
|
|
|
_map["handle-killpriv-v2"] = &handle_killpriv_v2; |
|
|
|
_map["ignorepponrename"] = &ignorepponrename; |
|
|
|
_map["inodecalc"] = &inodecalc; |
|
|
|
_map["kernel-permissions-check"] = &kernel_permissions_check; |
|
|
|
_map["kernel_cache"] = &kernel_cache; |
|
|
|
_map["lazy-umount-mountpoint"] = &lazy_umount_mountpoint; |
|
|
|
_map["link-exdev"] = &link_exdev; |
|
|
|
_map["link_cow"] = &link_cow; |
|
|
|
_map["log.metrics"] = &log_metrics; |
|
|
|
_map["minfreespace"] = &minfreespace; |
|
|
|
_map["mount"] = &mountpoint; |
|
|
|
_map["moveonenospc"] = &moveonenospc; |
|
|
|
_map["nfsopenhack"] = &nfsopenhack; |
|
|
|
_map["nullrw"] = &nullrw; |
|
|
|
_map["parallel-direct-writes"] = ¶llel_direct_writes; |
|
|
|
_map["passthrough"] = &passthrough; |
|
|
|
_map["cache.attr"] = &cache_attr; |
|
|
|
_map["cache.entry"] = &cache_entry; |
|
|
|
_map["cache.files"] = &cache_files; |
|
|
|
_map["cache.files.process-names"] = &cache_files_process_names; |
|
|
|
_map["cache.negative_entry"] = &cache_negative_entry; |
|
|
|
_map["cache.open"] = &_dummy; |
|
|
|
_map["cache.readdir"] = &cache_readdir; |
|
|
|
_map["cache.statfs"] = &cache_statfs; |
|
|
|
_map["cache.symlinks"] = &cache_symlinks; |
|
|
|
_map["cache.writeback"] = &cache_writeback; |
|
|
|
_map["category.action"] = &category.action; |
|
|
|
_map["category.create"] = &category.create; |
|
|
|
_map["category.search"] = &category.search; |
|
|
|
_map["config"] = &config_file; |
|
|
|
_map["debug"] = &debug; |
|
|
|
_map["direct-io-allow-mmap"] = &direct_io_allow_mmap; |
|
|
|
_map["direct_io"] = &_dummy; |
|
|
|
_map["dropcacheonclose"] = &dropcacheonclose; |
|
|
|
_map["export-support"] = &export_support; |
|
|
|
_map["flush-on-close"] = &flushonclose; |
|
|
|
_map["follow-symlinks"] = &follow_symlinks; |
|
|
|
_map["fsname"] = &fsname; |
|
|
|
_map["func.access"] = &func.access; |
|
|
|
_map["func.chmod"] = &func.chmod; |
|
|
|
_map["func.chown"] = &func.chown; |
|
|
|
_map["func.create"] = &func.create; |
|
|
|
_map["func.getattr"] = &func.getattr; |
|
|
|
_map["func.getxattr"] = &func.getxattr; |
|
|
|
_map["func.link"] = &func.link; |
|
|
|
_map["func.listxattr"] = &func.listxattr; |
|
|
|
_map["func.mkdir"] = &func.mkdir; |
|
|
|
_map["func.mknod"] = &func.mknod; |
|
|
|
_map["func.open"] = &func.open; |
|
|
|
_map["func.readdir"] = &readdir; |
|
|
|
_map["func.readlink"] = &func.readlink; |
|
|
|
_map["func.removexattr"] = &func.removexattr; |
|
|
|
_map["func.rename"] = &func.rename; |
|
|
|
_map["func.rmdir"] = &func.rmdir; |
|
|
|
_map["func.setxattr"] = &func.setxattr; |
|
|
|
_map["func.symlink"] = &func.symlink; |
|
|
|
_map["func.truncate"] = &func.truncate; |
|
|
|
_map["func.unlink"] = &func.unlink; |
|
|
|
_map["func.utimens"] = &func.utimens; |
|
|
|
_map["fuse_msg_size"] = &fuse_msg_size; |
|
|
|
_map["gid"] = &gid; |
|
|
|
_map["gid-cache-expire-timeout"] = &gid_cache_expire_timeout; |
|
|
|
_map["gid-cache-remove-timeout"] = &gid_cache_remove_timeout; |
|
|
|
_map["handle-killpriv"] = &handle_killpriv; |
|
|
|
_map["handle-killpriv-v2"] = &handle_killpriv_v2; |
|
|
|
_map["hard_remove"] = &_dummy; |
|
|
|
_map["ignorepponrename"] = &ignorepponrename; |
|
|
|
_map["inodecalc"] = &inodecalc; |
|
|
|
_map["kernel-permissions-check"] = &kernel_permissions_check; |
|
|
|
_map["kernel_cache"] = &_dummy; |
|
|
|
_map["lazy-umount-mountpoint"] = &lazy_umount_mountpoint; |
|
|
|
_map["link-exdev"] = &link_exdev; |
|
|
|
_map["link_cow"] = &link_cow; |
|
|
|
_map["log.metrics"] = &log_metrics; |
|
|
|
_map["minfreespace"] = &minfreespace; |
|
|
|
_map["mount"] = &mountpoint; |
|
|
|
_map["moveonenospc"] = &moveonenospc; |
|
|
|
_map["negative_entry"] = &_dummy; |
|
|
|
_map["nfsopenhack"] = &nfsopenhack; |
|
|
|
_map["no_splice_move"] = &_dummy; |
|
|
|
_map["no_split_write"] = &_dummy; |
|
|
|
_map["noforget"] = &noforget; |
|
|
|
_map["nonempty"] = &_dummy; |
|
|
|
_map["nullrw"] = &nullrw; |
|
|
|
_map["parallel-direct-writes"] = ¶llel_direct_writes; |
|
|
|
_map["passthrough"] = &passthrough; |
|
|
|
_map["passthrough-max-stack-depth"] = &passthrough_max_stack_depth; |
|
|
|
_map["pid"] = &pid; |
|
|
|
_map["pin-threads"] = &pin_threads; |
|
|
|
_map["posix_acl"] = &posix_acl; |
|
|
|
_map["process-thread-count"] = &process_thread_count; |
|
|
|
_map["process-thread-queue-depth"] = &process_thread_queue_depth; |
|
|
|
_map["proxy-ioprio"] = &proxy_ioprio; |
|
|
|
_map["read-thread-count"] = &read_thread_count; |
|
|
|
_map["readahead"] = &readahead; |
|
|
|
_map["readdirplus"] = &readdirplus; |
|
|
|
_map["remember-nodes"] = &remember_nodes; |
|
|
|
_map["rename-exdev"] = &rename_exdev; |
|
|
|
_map["scheduling-priority"] = &scheduling_priority; |
|
|
|
_map["security_capability"] = &security_capability; |
|
|
|
_map["srcmounts"] = &srcmounts; |
|
|
|
_map["statfs"] = &statfs; |
|
|
|
_map["statfs_ignore"] = &statfs_ignore; |
|
|
|
_map["symlinkify"] = &symlinkify; |
|
|
|
_map["symlinkify_timeout"] = &symlinkify_timeout; |
|
|
|
_map["threads"] = &threads; |
|
|
|
_map["uid"] = &uid; |
|
|
|
_map["umask"] = &umask; |
|
|
|
_map["version"] = &version; |
|
|
|
_map["xattr"] = &xattr; |
|
|
|
} |
|
|
|
|
|
|
|
Config& |
|
|
|
Config::operator=(const Config &cfg_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
std::string val; |
|
|
|
|
|
|
|
for(auto &kv : _map) |
|
|
|
{ |
|
|
|
rv = cfg_.get(kv.first,&val); |
|
|
|
if(rv) |
|
|
|
continue; |
|
|
|
|
|
|
|
kv.second->from_string(val); |
|
|
|
} |
|
|
|
|
|
|
|
return *this; |
|
|
|
_map["pid"] = &pid; |
|
|
|
_map["pin-threads"] = &pin_threads; |
|
|
|
_map["posix_acl"] = &posix_acl; |
|
|
|
_map["process-thread-count"] = &process_thread_count; |
|
|
|
_map["process-thread-queue-depth"] = &process_thread_queue_depth; |
|
|
|
_map["proxy-ioprio"] = &proxy_ioprio; |
|
|
|
_map["read-thread-count"] = &read_thread_count; |
|
|
|
_map["readahead"] = &readahead; |
|
|
|
_map["remember-nodes"] = &remember_nodes; |
|
|
|
_map["rename-exdev"] = &rename_exdev; |
|
|
|
_map["scheduling-priority"] = &scheduling_priority; |
|
|
|
_map["security_capability"] = &security_capability; |
|
|
|
_map["splice_move"] = &_dummy; |
|
|
|
_map["splice_read"] = &_dummy; |
|
|
|
_map["splice_write"] = &_dummy; |
|
|
|
_map["srcmounts"] = &srcmounts; |
|
|
|
_map["statfs"] = &statfs; |
|
|
|
_map["statfs_ignore"] = &statfs_ignore; |
|
|
|
_map["symlinkify"] = &symlinkify; |
|
|
|
_map["symlinkify_timeout"] = &symlinkify_timeout; |
|
|
|
_map["threads"] = &threads; |
|
|
|
_map["uid"] = &uid; |
|
|
|
_map["umask"] = &umask; |
|
|
|
_map["use_ino"] = &_dummy; |
|
|
|
_map["version"] = &version; |
|
|
|
_map["xattr"] = &xattr; |
|
|
|
} |
|
|
|
|
|
|
|
bool |
|
|
|
@ -317,6 +338,7 @@ Config::keys_listxattr_size() const |
|
|
|
{ |
|
|
|
if(val->display == false) |
|
|
|
continue; |
|
|
|
|
|
|
|
rv += sizeof("user.mergerfs."); |
|
|
|
rv += key.size(); |
|
|
|
} |
|
|
|
@ -395,16 +417,13 @@ Config::set(const std::string &kv_) |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
Config::from_stream(std::istream &istrm_, |
|
|
|
ErrVec *errs_) |
|
|
|
Config::from_stream(std::istream &istrm_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
std::string line; |
|
|
|
std::string key; |
|
|
|
std::string val; |
|
|
|
Config newcfg; |
|
|
|
|
|
|
|
newcfg = *this; |
|
|
|
Config::ErrVec new_errs; |
|
|
|
|
|
|
|
while(std::getline(istrm_,line,'\n')) |
|
|
|
{ |
|
|
|
@ -416,22 +435,21 @@ Config::from_stream(std::istream &istrm_, |
|
|
|
key = str::trim(key); |
|
|
|
val = str::trim(val); |
|
|
|
|
|
|
|
rv = newcfg.set(key,val); |
|
|
|
rv = set(key,val); |
|
|
|
if(rv < 0) |
|
|
|
errs_->push_back({rv,key}); |
|
|
|
new_errs.push_back({-rv,key+'='+val}); |
|
|
|
} |
|
|
|
|
|
|
|
if(!errs_->empty()) |
|
|
|
return -EINVAL; |
|
|
|
|
|
|
|
*this = newcfg; |
|
|
|
rv = (new_errs.empty() ? 0 : -EINVAL); |
|
|
|
errs.insert(errs.end(), |
|
|
|
new_errs.begin(), |
|
|
|
new_errs.end()); |
|
|
|
|
|
|
|
return 0; |
|
|
|
return rv; |
|
|
|
} |
|
|
|
|
|
|
|
int |
|
|
|
Config::from_file(const std::string &filepath_, |
|
|
|
ErrVec *errs_) |
|
|
|
Config::from_file(const std::string &filepath_) |
|
|
|
{ |
|
|
|
int rv; |
|
|
|
std::ifstream ifstrm; |
|
|
|
@ -439,11 +457,11 @@ Config::from_file(const std::string &filepath_, |
|
|
|
ifstrm.open(filepath_); |
|
|
|
if(!ifstrm.good()) |
|
|
|
{ |
|
|
|
errs_->push_back({-errno,filepath_}); |
|
|
|
errs.push_back({errno,filepath_}); |
|
|
|
return -errno; |
|
|
|
} |
|
|
|
|
|
|
|
rv = from_stream(ifstrm,errs_); |
|
|
|
rv = from_stream(ifstrm); |
|
|
|
|
|
|
|
ifstrm.close(); |
|
|
|
|
|
|
|
@ -500,52 +518,31 @@ Config::prune_cmd_xattr(const std::string_view &s_) |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
std::ostream& |
|
|
|
operator<<(std::ostream &os_, |
|
|
|
const Config &c_) |
|
|
|
{ |
|
|
|
for(const auto &[key,val] : c_._map) |
|
|
|
os_ << key << '=' << val->to_string() << std::endl; |
|
|
|
|
|
|
|
return os_; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static |
|
|
|
std::string |
|
|
|
err2str(const int err_) |
|
|
|
Config::Err::to_string() const |
|
|
|
{ |
|
|
|
switch(err_) |
|
|
|
std::string s; |
|
|
|
|
|
|
|
switch(err) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
return std::string(); |
|
|
|
case -EINVAL: |
|
|
|
return "invalid value"; |
|
|
|
case -ENOATTR: |
|
|
|
return "unknown option"; |
|
|
|
case -EROFS: |
|
|
|
return "read-only option"; |
|
|
|
break; |
|
|
|
case EINVAL: |
|
|
|
s = "invalid value"; |
|
|
|
break; |
|
|
|
case ENOATTR: |
|
|
|
s = "unknown option"; |
|
|
|
break; |
|
|
|
case EROFS: |
|
|
|
s = "read-only option"; |
|
|
|
break; |
|
|
|
case ELOOP: |
|
|
|
s = "too many levels of config"; |
|
|
|
break; |
|
|
|
default: |
|
|
|
return strerror(-err_); |
|
|
|
} |
|
|
|
|
|
|
|
return std::string(); |
|
|
|
} |
|
|
|
|
|
|
|
std::ostream& |
|
|
|
operator<<(std::ostream &os_, |
|
|
|
const Config::ErrVec &ev_) |
|
|
|
{ |
|
|
|
std::string errstr; |
|
|
|
|
|
|
|
for(auto &err : ev_) |
|
|
|
{ |
|
|
|
os_ << "* ERROR: "; |
|
|
|
errstr = err2str(err.err); |
|
|
|
if(!errstr.empty()) |
|
|
|
os_ << errstr << " - "; |
|
|
|
os_ << err.str << std::endl; |
|
|
|
s = strerror(err); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return os_; |
|
|
|
return fmt::format("{} - {}",s,str); |
|
|
|
} |