mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-17 00:10:03 -04:00
Add metadata-as-JSON support to dwarfsck
This commit is contained in:
parent
a68657724a
commit
3f5c84a67a
@ -33,6 +33,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <folly/Expected.h>
|
||||
|
||||
#include "dwarfs/metadata_types.h"
|
||||
@ -69,6 +70,10 @@ class filesystem_v2 {
|
||||
impl_->dump(os, detail_level);
|
||||
}
|
||||
|
||||
folly::dynamic metadata_as_dynamic() const {
|
||||
return impl_->metadata_as_dynamic();
|
||||
}
|
||||
|
||||
void walk(std::function<void(entry_view)> const& func) const {
|
||||
impl_->walk(func);
|
||||
}
|
||||
@ -128,6 +133,7 @@ class filesystem_v2 {
|
||||
virtual ~impl() = default;
|
||||
|
||||
virtual void dump(std::ostream& os, int detail_level) const = 0;
|
||||
virtual folly::dynamic metadata_as_dynamic() const = 0;
|
||||
virtual void walk(std::function<void(entry_view)> const& func) const = 0;
|
||||
virtual std::optional<entry_view> find(const char* path) const = 0;
|
||||
virtual std::optional<entry_view> find(int inode) const = 0;
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <folly/dynamic.h>
|
||||
#include <folly/Expected.h>
|
||||
#include <folly/Range.h>
|
||||
|
||||
@ -68,6 +69,10 @@ class metadata_v2 {
|
||||
impl_->dump(os, detail_level, icb);
|
||||
}
|
||||
|
||||
folly::dynamic as_dynamic() const {
|
||||
return impl_->as_dynamic();
|
||||
}
|
||||
|
||||
static void get_stat_defaults(struct ::stat* defaults);
|
||||
|
||||
// TODO: check if this is needed
|
||||
@ -138,6 +143,8 @@ class metadata_v2 {
|
||||
std::ostream& os, int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const = 0;
|
||||
|
||||
virtual folly::dynamic as_dynamic() const = 0;
|
||||
|
||||
virtual size_t size() const = 0;
|
||||
virtual bool empty() const = 0;
|
||||
|
||||
|
@ -195,6 +195,7 @@ class filesystem_ : public filesystem_v2::impl {
|
||||
const struct ::stat* stat_defaults, int inode_offset);
|
||||
|
||||
void dump(std::ostream& os, int detail_level) const override;
|
||||
folly::dynamic metadata_as_dynamic() const override;
|
||||
void walk(std::function<void(entry_view)> const& func) const override;
|
||||
std::optional<entry_view> find(const char* path) const override;
|
||||
std::optional<entry_view> find(int inode) const override;
|
||||
@ -273,6 +274,11 @@ void filesystem_<LoggerPolicy>::dump(std::ostream& os, int detail_level) const {
|
||||
});
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
folly::dynamic filesystem_<LoggerPolicy>::metadata_as_dynamic() const {
|
||||
return meta_.as_dynamic();
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
void filesystem_<LoggerPolicy>::walk(
|
||||
std::function<void(entry_view)> const& func) const {
|
||||
|
@ -158,6 +158,8 @@ class metadata_ : public metadata_v2::impl {
|
||||
std::function<void(const std::string&, uint32_t)> const& icb)
|
||||
const override;
|
||||
|
||||
folly::dynamic as_dynamic() const override;
|
||||
|
||||
size_t size() const override { return data_.size(); }
|
||||
|
||||
bool empty() const override { return data_.empty(); }
|
||||
@ -275,6 +277,9 @@ class metadata_ : public metadata_v2::impl {
|
||||
int detail_level,
|
||||
std::function<void(const std::string&, uint32_t)> const& icb) const;
|
||||
|
||||
folly::dynamic as_dynamic(entry_view entry) const;
|
||||
folly::dynamic as_dynamic(directory_view dir) const;
|
||||
|
||||
std::optional<entry_view>
|
||||
find(directory_view dir, std::string_view name) const;
|
||||
|
||||
@ -439,6 +444,76 @@ void metadata_<LoggerPolicy>::dump(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
folly::dynamic metadata_<LoggerPolicy>::as_dynamic(directory_view dir) const {
|
||||
folly::dynamic obj = folly::dynamic::array;
|
||||
|
||||
auto count = dir.entry_count();
|
||||
auto first = dir.first_entry();
|
||||
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
obj.push_back(as_dynamic(make_entry_view(first + i)));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
folly::dynamic metadata_<LoggerPolicy>::as_dynamic(entry_view entry) const {
|
||||
folly::dynamic obj = folly::dynamic::object;
|
||||
|
||||
auto mode = entry.mode();
|
||||
auto inode = entry.inode();
|
||||
|
||||
obj["mode"] = mode;
|
||||
obj["modestring"] = modestring(mode);
|
||||
obj["inode"] = inode;
|
||||
|
||||
if (inode > 0) {
|
||||
obj["name"] = std::string(entry.name());
|
||||
}
|
||||
|
||||
if (S_ISREG(mode)) {
|
||||
obj["type"] = "file";
|
||||
obj["size"] = file_size(entry, mode);
|
||||
} else if (S_ISDIR(mode)) {
|
||||
obj["type"] = "directory";
|
||||
obj["entries"] = as_dynamic(make_directory_view(entry));
|
||||
} else if (S_ISLNK(mode)) {
|
||||
obj["type"] = "link";
|
||||
obj["target"] = std::string(link_value(entry));
|
||||
} else if (S_ISBLK(mode)) {
|
||||
obj["type"] = "blockdev";
|
||||
obj["device_id"] = get_device_id(inode);
|
||||
} else if (S_ISCHR(mode)) {
|
||||
obj["type"] = "chardev";
|
||||
obj["device_id"] = get_device_id(inode);
|
||||
} else if (S_ISFIFO(mode)) {
|
||||
obj["type"] = "fifo";
|
||||
} else if (S_ISSOCK(mode)) {
|
||||
obj["type"] = "socket";
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
folly::dynamic metadata_<LoggerPolicy>::as_dynamic() const {
|
||||
folly::dynamic obj = folly::dynamic::object;
|
||||
|
||||
struct ::statvfs stbuf;
|
||||
statvfs(&stbuf);
|
||||
|
||||
obj["statvfs"] = folly::dynamic::object
|
||||
("f_bsize", stbuf.f_bsize)
|
||||
("f_files", stbuf.f_files)
|
||||
("f_blocks", stbuf.f_blocks);
|
||||
|
||||
obj["root"] = as_dynamic(root_);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
template <typename LoggerPolicy>
|
||||
std::string metadata_<LoggerPolicy>::modestring(uint16_t mode) const {
|
||||
std::ostringstream oss;
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include <folly/json.h>
|
||||
#include <folly/String.h>
|
||||
|
||||
#include "dwarfs/filesystem_v2.h"
|
||||
@ -38,6 +39,7 @@ namespace po = boost::program_options;
|
||||
int dwarfsck(int argc, char** argv) {
|
||||
std::string log_level, input;
|
||||
int detail;
|
||||
bool json;
|
||||
|
||||
// clang-format off
|
||||
po::options_description opts("Command line options");
|
||||
@ -48,6 +50,9 @@ int dwarfsck(int argc, char** argv) {
|
||||
("detail,d",
|
||||
po::value<int>(&detail)->default_value(1),
|
||||
"detail level")
|
||||
("json",
|
||||
po::value<bool>(&json)->zero_tokens(),
|
||||
"print metadata in JSON format")
|
||||
("log-level",
|
||||
po::value<std::string>(&log_level)->default_value("info"),
|
||||
"log level (error, warn, info, debug, trace)")
|
||||
@ -74,7 +79,12 @@ int dwarfsck(int argc, char** argv) {
|
||||
|
||||
auto mm = std::make_shared<dwarfs::mmap>(input);
|
||||
|
||||
dwarfs::filesystem_v2::identify(lgr, mm, std::cout, detail);
|
||||
if (json) {
|
||||
dwarfs::filesystem_v2 fs(lgr, mm);
|
||||
std::cout << folly::toPrettyJson(fs.metadata_as_dynamic()) << std::endl;
|
||||
} else {
|
||||
dwarfs::filesystem_v2::identify(lgr, mm, std::cout, detail);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user