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