mirror of https://github.com/trapexit/mergerfs.git
13 changed files with 391 additions and 42 deletions
-
2Makefile
-
1mergerfs.spec
-
7mkdocs/build-venv
-
36mkdocs/docs/support.md
-
6src/fsck_mergerfs.hpp
-
11src/mergerfs.cpp
-
68src/mergerfs_api.cpp
-
24src/mergerfs_api.hpp
-
227src/mergerfs_collect_info.cpp
-
11src/mergerfs_collect_info.hpp
-
24src/mergerfs_fsck.cpp
-
9src/mergerfs_fsck.hpp
-
7src/mergerfs_ioctl.hpp
@ -0,0 +1,7 @@ |
|||||
|
#!/bin/sh |
||||
|
set -x |
||||
|
set -e |
||||
|
|
||||
|
python3 -m venv venv |
||||
|
. ./venv/bin/activate |
||||
|
pip3 install --no-cache-dir mkdocs mkdocs-material pymdown-extensions mike |
@ -1,6 +0,0 @@ |
|||||
#pragma once
|
|
||||
|
|
||||
namespace fsck |
|
||||
{ |
|
||||
int main(int argc, char **argv); |
|
||||
} |
|
@ -0,0 +1,68 @@ |
|||||
|
#include "mergerfs_api.hpp"
|
||||
|
|
||||
|
#include "fs_close.hpp"
|
||||
|
#include "fs_ioctl.hpp"
|
||||
|
#include "fs_open.hpp"
|
||||
|
#include "mergerfs_ioctl.hpp"
|
||||
|
#include "fs_lgetxattr.hpp"
|
||||
|
|
||||
|
#include "str.hpp"
|
||||
|
|
||||
|
#include "scope_guard.hpp"
|
||||
|
|
||||
|
#include <string.h>
|
||||
|
|
||||
|
|
||||
|
int |
||||
|
mergerfs::api::allpaths(const std::string &input_path_, |
||||
|
std::vector<std::string> &output_paths_) |
||||
|
{ |
||||
|
int rv; |
||||
|
IOCTL_BUF buf; |
||||
|
|
||||
|
rv = fs::lgetxattr(input_path_,"user.mergerfs.allpaths",buf,sizeof(buf)); |
||||
|
if(rv < 0) |
||||
|
return rv; |
||||
|
|
||||
|
str::split_on_null(buf,rv,&output_paths_); |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
_lgetxattr(const std::string &input_path_, |
||||
|
const std::string &key_, |
||||
|
std::string &value_) |
||||
|
{ |
||||
|
int rv; |
||||
|
IOCTL_BUF buf; |
||||
|
|
||||
|
rv = fs::lgetxattr(input_path_,key_,buf,sizeof(buf)); |
||||
|
if(rv < 0) |
||||
|
return rv; |
||||
|
|
||||
|
value_ = buf; |
||||
|
|
||||
|
return rv; |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
mergerfs::api::basepath(const std::string &input_path_, |
||||
|
std::string &basepath_) |
||||
|
{ |
||||
|
return ::_lgetxattr(input_path_,"user.mergerfs.basepath",basepath_); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
mergerfs::api::relpath(const std::string &input_path_, |
||||
|
std::string &relpath_) |
||||
|
{ |
||||
|
return ::_lgetxattr(input_path_,"user.mergerfs.relpath",relpath_); |
||||
|
} |
||||
|
|
||||
|
int |
||||
|
mergerfs::api::fullpath(const std::string &input_path_, |
||||
|
std::string &fullpath_) |
||||
|
{ |
||||
|
return ::_lgetxattr(input_path_,"user.mergerfs.fullpath",fullpath_); |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
#include <string>
|
||||
|
#include <vector>
|
||||
|
|
||||
|
|
||||
|
namespace mergerfs |
||||
|
{ |
||||
|
namespace api |
||||
|
{ |
||||
|
int |
||||
|
basepath(const std::string &path, |
||||
|
std::string &basepath); |
||||
|
int |
||||
|
relpath(const std::string &path, |
||||
|
std::string &relpath); |
||||
|
int |
||||
|
fullpath(const std::string &path, |
||||
|
std::string &fullpath); |
||||
|
int |
||||
|
allpaths(const std::string &path, |
||||
|
std::vector<std::string> &paths); |
||||
|
} |
||||
|
} |
@ -0,0 +1,227 @@ |
|||||
|
#include "mergerfs_collect_info.hpp"
|
||||
|
|
||||
|
#include "mergerfs_api.hpp"
|
||||
|
#include "fs_mounts.hpp"
|
||||
|
#include "fs_unlink.hpp"
|
||||
|
|
||||
|
#include "CLI11.hpp"
|
||||
|
#include "fmt/core.h"
|
||||
|
#include "scope_guard.hpp"
|
||||
|
#include "subprocess.hpp"
|
||||
|
|
||||
|
#include <stdio.h>
|
||||
|
|
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_write_str(const std::string &output_, |
||||
|
const std::string &str_) |
||||
|
{ |
||||
|
FILE *f; |
||||
|
|
||||
|
f = ::fopen(output_.c_str(),"a"); |
||||
|
if(f == NULL) |
||||
|
return; |
||||
|
DEFER{ ::fclose(f); }; |
||||
|
|
||||
|
::fwrite(str_.c_str(),1,str_.size(),f); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_lsblk(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"lsblk", |
||||
|
"--json", |
||||
|
"-o","NAME,FSTYPE,FSSIZE,SIZE,MOUNTPOINTS,RM,RO,ROTA" |
||||
|
}; |
||||
|
|
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_mounts(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"cat", |
||||
|
"/proc/mounts" |
||||
|
}; |
||||
|
|
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_mount_point_stats(const std::string &output_) |
||||
|
{ |
||||
|
fs::MountVec mounts; |
||||
|
|
||||
|
fs::mounts(mounts); |
||||
|
|
||||
|
for(const auto &mount : mounts) |
||||
|
{ |
||||
|
std::vector<std::string> allpaths; |
||||
|
|
||||
|
mergerfs::api::allpaths(mount.dir.string(),allpaths); |
||||
|
for(const auto &path : allpaths) |
||||
|
{ |
||||
|
auto args = {"stat",path.c_str()}; |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_mergerfs_version(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"mergerfs", |
||||
|
"--version" |
||||
|
}; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_uname(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"uname", |
||||
|
"-a" |
||||
|
}; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_lsb_release(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"lsb_release", |
||||
|
"-a" |
||||
|
}; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_df(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"df", |
||||
|
"-h" |
||||
|
}; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
static |
||||
|
void |
||||
|
_fstab(const std::string &output_) |
||||
|
{ |
||||
|
auto args = |
||||
|
{ |
||||
|
"cat", |
||||
|
"/etc/fstab" |
||||
|
}; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
subprocess::call(args, |
||||
|
subprocess::output{output_.c_str()}); |
||||
|
} |
||||
|
catch(...) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
int |
||||
|
mergerfs::collect_info::main(int argc_, |
||||
|
char **argv_) |
||||
|
{ |
||||
|
CLI::App app; |
||||
|
const char *output_filepath = "/tmp/mergerfs.info.txt"; |
||||
|
|
||||
|
app.description("mergerfs.collect-info:" |
||||
|
" Collect info for support requests"); |
||||
|
app.name("USAGE: mergerfs.collect-info"); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
app.parse(argc_,argv_); |
||||
|
} |
||||
|
catch(const CLI::ParseError &e) |
||||
|
{ |
||||
|
return app.exit(e); |
||||
|
} |
||||
|
|
||||
|
fmt::print("* Please have mergerfs mounted before running this tool.\n"); |
||||
|
|
||||
|
fs::unlink(output_filepath); |
||||
|
::_write_str(output_filepath,"::mergerfs --version::\n"); |
||||
|
::_mergerfs_version(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::uname -a::\n"); |
||||
|
::_uname(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::lsb_release -a::\n"); |
||||
|
::_lsb_release(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::df -h::\n"); |
||||
|
::_df(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::lsblk::\n"); |
||||
|
::_lsblk(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::cat /proc/mounts::\n"); |
||||
|
::_mounts(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::mount point stats::\n"); |
||||
|
::_mount_point_stats(output_filepath); |
||||
|
::_write_str(output_filepath,"\n::cat /etc/fstab::\n"); |
||||
|
::_fstab(output_filepath); |
||||
|
|
||||
|
fmt::print("* Upload the following file to your" |
||||
|
" GitHub ticket or put on https://pastebin.com" |
||||
|
" when requesting support.\n* {}\n",output_filepath); |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,11 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
namespace mergerfs |
||||
|
{ |
||||
|
namespace collect_info |
||||
|
{ |
||||
|
int |
||||
|
main(int argc, |
||||
|
char **argv); |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#pragma once
|
||||
|
|
||||
|
namespace mergerfs |
||||
|
{ |
||||
|
namespace fsck |
||||
|
{ |
||||
|
int main(int argc, char **argv); |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue