mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-18 17:00:30 -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 <sys/types.h>
|
||||||
|
|
||||||
|
#include <folly/dynamic.h>
|
||||||
#include <folly/Expected.h>
|
#include <folly/Expected.h>
|
||||||
|
|
||||||
#include "dwarfs/metadata_types.h"
|
#include "dwarfs/metadata_types.h"
|
||||||
@ -69,6 +70,10 @@ class filesystem_v2 {
|
|||||||
impl_->dump(os, detail_level);
|
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 {
|
void walk(std::function<void(entry_view)> const& func) const {
|
||||||
impl_->walk(func);
|
impl_->walk(func);
|
||||||
}
|
}
|
||||||
@ -128,6 +133,7 @@ class filesystem_v2 {
|
|||||||
virtual ~impl() = default;
|
virtual ~impl() = default;
|
||||||
|
|
||||||
virtual void dump(std::ostream& os, int detail_level) const = 0;
|
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 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(const char* path) const = 0;
|
||||||
virtual std::optional<entry_view> find(int inode) const = 0;
|
virtual std::optional<entry_view> find(int inode) const = 0;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <folly/dynamic.h>
|
||||||
#include <folly/Expected.h>
|
#include <folly/Expected.h>
|
||||||
#include <folly/Range.h>
|
#include <folly/Range.h>
|
||||||
|
|
||||||
@ -68,6 +69,10 @@ class metadata_v2 {
|
|||||||
impl_->dump(os, detail_level, icb);
|
impl_->dump(os, detail_level, icb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
folly::dynamic as_dynamic() const {
|
||||||
|
return impl_->as_dynamic();
|
||||||
|
}
|
||||||
|
|
||||||
static void get_stat_defaults(struct ::stat* defaults);
|
static void get_stat_defaults(struct ::stat* defaults);
|
||||||
|
|
||||||
// TODO: check if this is needed
|
// TODO: check if this is needed
|
||||||
@ -138,6 +143,8 @@ class metadata_v2 {
|
|||||||
std::ostream& os, int detail_level,
|
std::ostream& os, int detail_level,
|
||||||
std::function<void(const std::string&, uint32_t)> const& icb) const = 0;
|
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 size_t size() const = 0;
|
||||||
virtual bool empty() 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);
|
const struct ::stat* stat_defaults, int inode_offset);
|
||||||
|
|
||||||
void dump(std::ostream& os, int detail_level) const override;
|
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;
|
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(const char* path) const override;
|
||||||
std::optional<entry_view> find(int inode) 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>
|
template <typename LoggerPolicy>
|
||||||
void filesystem_<LoggerPolicy>::walk(
|
void filesystem_<LoggerPolicy>::walk(
|
||||||
std::function<void(entry_view)> const& func) const {
|
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)
|
std::function<void(const std::string&, uint32_t)> const& icb)
|
||||||
const override;
|
const override;
|
||||||
|
|
||||||
|
folly::dynamic as_dynamic() const override;
|
||||||
|
|
||||||
size_t size() const override { return data_.size(); }
|
size_t size() const override { return data_.size(); }
|
||||||
|
|
||||||
bool empty() const override { return data_.empty(); }
|
bool empty() const override { return data_.empty(); }
|
||||||
@ -275,6 +277,9 @@ class metadata_ : public metadata_v2::impl {
|
|||||||
int detail_level,
|
int detail_level,
|
||||||
std::function<void(const std::string&, uint32_t)> const& icb) const;
|
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>
|
std::optional<entry_view>
|
||||||
find(directory_view dir, std::string_view name) const;
|
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>
|
template <typename LoggerPolicy>
|
||||||
std::string metadata_<LoggerPolicy>::modestring(uint16_t mode) const {
|
std::string metadata_<LoggerPolicy>::modestring(uint16_t mode) const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
#include <folly/json.h>
|
||||||
#include <folly/String.h>
|
#include <folly/String.h>
|
||||||
|
|
||||||
#include "dwarfs/filesystem_v2.h"
|
#include "dwarfs/filesystem_v2.h"
|
||||||
@ -38,6 +39,7 @@ namespace po = boost::program_options;
|
|||||||
int dwarfsck(int argc, char** argv) {
|
int dwarfsck(int argc, char** argv) {
|
||||||
std::string log_level, input;
|
std::string log_level, input;
|
||||||
int detail;
|
int detail;
|
||||||
|
bool json;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
po::options_description opts("Command line options");
|
po::options_description opts("Command line options");
|
||||||
@ -48,6 +50,9 @@ int dwarfsck(int argc, char** argv) {
|
|||||||
("detail,d",
|
("detail,d",
|
||||||
po::value<int>(&detail)->default_value(1),
|
po::value<int>(&detail)->default_value(1),
|
||||||
"detail level")
|
"detail level")
|
||||||
|
("json",
|
||||||
|
po::value<bool>(&json)->zero_tokens(),
|
||||||
|
"print metadata in JSON format")
|
||||||
("log-level",
|
("log-level",
|
||||||
po::value<std::string>(&log_level)->default_value("info"),
|
po::value<std::string>(&log_level)->default_value("info"),
|
||||||
"log level (error, warn, info, debug, trace)")
|
"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);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user