mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-13 06:16:55 -04:00
Improve dwarfsck
This commit is contained in:
parent
6da776d4e6
commit
87d547aaae
@ -46,6 +46,8 @@ class progress;
|
||||
|
||||
class filesystem_v2 {
|
||||
public:
|
||||
filesystem_v2(logger& lgr, std::shared_ptr<mmif> mm);
|
||||
|
||||
filesystem_v2(logger& lgr, std::shared_ptr<mmif> mm,
|
||||
const block_cache_options& bc_options,
|
||||
const struct ::stat* stat_defaults = nullptr,
|
||||
|
@ -77,6 +77,11 @@ std::shared_ptr<filesystem_v2> s_fs;
|
||||
|
||||
void op_init(void* /*userdata*/, struct fuse_conn_info* /*conn*/) {
|
||||
DEBUG_FUNC("")
|
||||
|
||||
log_proxy<debug_logger_policy> log(s_lgr);
|
||||
|
||||
auto ti = log.timed_info();
|
||||
|
||||
block_cache_options bco;
|
||||
bco.max_bytes = opts.cachesize;
|
||||
bco.num_workers = opts.workers;
|
||||
@ -84,6 +89,8 @@ void op_init(void* /*userdata*/, struct fuse_conn_info* /*conn*/) {
|
||||
s_fs = std::make_shared<filesystem_v2>(
|
||||
s_lgr, std::make_shared<mmap>(opts.fsimage), bco, &opts.stat_defaults,
|
||||
FUSE_ROOT_ID);
|
||||
|
||||
ti << "file system initialized";
|
||||
}
|
||||
|
||||
void op_destroy(void* /*userdata*/) {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "dwarfs/filesystem_writer.h"
|
||||
#include "dwarfs/fstypes.h"
|
||||
#include "dwarfs/inode_reader_v2.h"
|
||||
#include "dwarfs/options.h"
|
||||
#include "dwarfs/progress.h"
|
||||
|
||||
namespace dwarfs {
|
||||
@ -330,13 +331,16 @@ ssize_t filesystem_<LoggerPolicy>::readv(uint32_t inode, iovec_read_buf& buf,
|
||||
|
||||
} // namespace
|
||||
|
||||
filesystem_v2::filesystem_v2(logger& lgr, std::shared_ptr<mmif> mm)
|
||||
: filesystem_v2(lgr, std::move(mm), block_cache_options()) {}
|
||||
|
||||
filesystem_v2::filesystem_v2(logger& lgr, std::shared_ptr<mmif> mm,
|
||||
const block_cache_options& bc_options,
|
||||
const struct ::stat* stat_defaults,
|
||||
int inode_offset)
|
||||
: impl_(make_unique_logging_object<filesystem_v2::impl, filesystem_,
|
||||
logger_policies>(
|
||||
lgr, mm, bc_options, stat_defaults, inode_offset)) {}
|
||||
lgr, std::move(mm), bc_options, stat_defaults, inode_offset)) {}
|
||||
|
||||
void filesystem_v2::rewrite(logger& lgr, progress& prog,
|
||||
std::shared_ptr<mmif> mm,
|
||||
@ -412,12 +416,9 @@ void filesystem_v2::identify(logger& lgr, std::shared_ptr<mmif> mm,
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint8_t> schema_raw;
|
||||
std::vector<uint8_t> meta_raw;
|
||||
|
||||
auto meta = make_metadata(lgr, mm, sections, schema_raw, meta_raw);
|
||||
|
||||
meta.dump(os, detail_level, [](const std::string&, uint32_t) {});
|
||||
if (detail_level > 0) {
|
||||
filesystem_v2(lgr, mm).dump(os, detail_level);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dwarfs
|
||||
|
@ -151,8 +151,10 @@ class metadata_ : public metadata_v2::impl {
|
||||
}
|
||||
|
||||
void dump(std::ostream& os, const std::string& indent, entry_view entry,
|
||||
int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const;
|
||||
void dump(std::ostream& os, const std::string& indent, directory_view dir,
|
||||
int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const;
|
||||
|
||||
std::optional<entry_view>
|
||||
@ -209,6 +211,7 @@ class metadata_ : public metadata_v2::impl {
|
||||
template <typename LoggerPolicy>
|
||||
void metadata_<LoggerPolicy>::dump(
|
||||
std::ostream& os, const std::string& indent, entry_view entry,
|
||||
int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
||||
auto mode = entry.mode();
|
||||
auto inode = entry.inode();
|
||||
@ -224,9 +227,12 @@ void metadata_<LoggerPolicy>::dump(
|
||||
uint32_t end = meta_.chunk_index()[inode - chunk_index_offset_ + 1];
|
||||
os << " [" << beg << ", " << end << "]";
|
||||
os << " " << file_size(entry, mode) << "\n";
|
||||
if (detail_level > 3) {
|
||||
icb(indent + " ", inode);
|
||||
}
|
||||
} else if (S_ISDIR(mode)) {
|
||||
dump(os, indent + " ", make_directory_view(entry), std::move(icb));
|
||||
dump(os, indent + " ", make_directory_view(entry), detail_level,
|
||||
std::move(icb));
|
||||
} else if (S_ISLNK(mode)) {
|
||||
os << " -> " << link_value(entry) << "\n";
|
||||
} else {
|
||||
@ -237,6 +243,7 @@ void metadata_<LoggerPolicy>::dump(
|
||||
template <typename LoggerPolicy>
|
||||
void metadata_<LoggerPolicy>::dump(
|
||||
std::ostream& os, const std::string& indent, directory_view dir,
|
||||
int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const {
|
||||
auto count = dir.entry_count();
|
||||
auto first = dir.first_entry();
|
||||
@ -245,7 +252,7 @@ void metadata_<LoggerPolicy>::dump(
|
||||
<< dir.parent_inode() << "]\n";
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
dump(os, indent, make_entry_view(first + i), icb);
|
||||
dump(os, indent, make_entry_view(first + i), detail_level, icb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,16 +263,22 @@ void metadata_<LoggerPolicy>::dump(
|
||||
struct ::statvfs stbuf;
|
||||
statvfs(&stbuf);
|
||||
|
||||
if (detail_level > 0) {
|
||||
os << "block size: " << stbuf.f_bsize << std::endl;
|
||||
os << "inode count: " << stbuf.f_files << std::endl;
|
||||
os << "original filesystem size: " << stbuf.f_blocks << std::endl;
|
||||
|
||||
if (detail_level > 0) {
|
||||
analyze_frozen(os, meta_);
|
||||
}
|
||||
|
||||
if (detail_level > 1) {
|
||||
dump(os, "", root_, icb);
|
||||
analyze_frozen(os, meta_);
|
||||
}
|
||||
|
||||
if (detail_level > 2) {
|
||||
dump(os, "", root_, detail_level, icb);
|
||||
}
|
||||
|
||||
if (detail_level > 4) {
|
||||
os << ::apache::thrift::debugString(meta_.thaw());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,39 +22,69 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <folly/String.h>
|
||||
|
||||
#include "dwarfs/filesystem_v2.h"
|
||||
#include "dwarfs/mmap.h"
|
||||
#include "dwarfs/options.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 2 || argc == 3) {
|
||||
try {
|
||||
dwarfs::stream_logger lgr(std::cerr, dwarfs::logger::DEBUG);
|
||||
auto mm = std::make_shared<dwarfs::mmap>(argv[1]);
|
||||
dwarfs::filesystem_v2 fs(lgr, mm, dwarfs::block_cache_options());
|
||||
namespace dwarfs {
|
||||
|
||||
if (argc == 3) {
|
||||
auto entry = fs.find(argv[2]);
|
||||
namespace po = boost::program_options;
|
||||
|
||||
if (entry) {
|
||||
struct ::stat stbuf;
|
||||
fs.getattr(*entry, &stbuf);
|
||||
std::vector<char> data(stbuf.st_size);
|
||||
fs.read(stbuf.st_ino, &data[0], data.size(), 0);
|
||||
std::cout.write(&data[0], data.size());
|
||||
}
|
||||
} else {
|
||||
// TODO: add more usage options...
|
||||
dwarfs::filesystem_v2::identify(lgr, mm, std::cout, 1);
|
||||
// fs.dump(std::cout, 1);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Usage: " << argv[0] << " file" << std::endl;
|
||||
int dwarfsck(int argc, char** argv) {
|
||||
std::string log_level, input;
|
||||
int detail;
|
||||
|
||||
// clang-format off
|
||||
po::options_description opts("Command line options");
|
||||
opts.add_options()
|
||||
("input,i",
|
||||
po::value<std::string>(&input),
|
||||
"input filesystem")
|
||||
("detail,d",
|
||||
po::value<int>(&detail)->default_value(1),
|
||||
"detail level")
|
||||
("log-level",
|
||||
po::value<std::string>(&log_level)->default_value("info"),
|
||||
"log level (error, warn, info, debug, trace)")
|
||||
("help,h",
|
||||
"output help message and exit");
|
||||
// clang-format on
|
||||
|
||||
po::positional_options_description pos;
|
||||
pos.add("input", -1);
|
||||
|
||||
po::variables_map vm;
|
||||
|
||||
po::store(
|
||||
po::command_line_parser(argc, argv).options(opts).positional(pos).run(),
|
||||
vm);
|
||||
po::notify(vm);
|
||||
|
||||
if (vm.count("help") or !vm.count("input")) {
|
||||
std::cout << "dwarfsck (" << DWARFS_VERSION << ")\n" << opts << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
dwarfs::stream_logger lgr(std::cerr, logger::parse_level(log_level));
|
||||
|
||||
auto mm = std::make_shared<dwarfs::mmap>(input);
|
||||
|
||||
dwarfs::filesystem_v2::identify(lgr, mm, std::cout, detail);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace dwarfs
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
try {
|
||||
return dwarfs::dwarfsck(argc, argv);
|
||||
} catch (std::exception const& e) {
|
||||
std::cerr << "ERROR: " << folly::exceptionStr(e) << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user