From: zhangdaolong Date: Mon, 7 Sep 2020 01:00:10 +0000 (+0800) Subject: os/bluestore/bluestore_tool: Add subcommand blufs-import X-Git-Tag: v17.1.0~2292^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=39118421dc6b7c68ffe39cf44588b8c773150e81;p=ceph-ci.git os/bluestore/bluestore_tool: Add subcommand blufs-import Examples ceph-bluestore-tool bluefs-import --path /var/lib/ceph/osd/ceph-1 --input-file ./db/CURRENT --dest-file db/CURRENT Signed-off-by: zhang daolong --- diff --git a/src/os/bluestore/bluestore_tool.cc b/src/os/bluestore/bluestore_tool.cc index 12293fdfd1b..e3470385b8b 100644 --- a/src/os/bluestore/bluestore_tool.cc +++ b/src/os/bluestore/bluestore_tool.cc @@ -6,7 +6,15 @@ #include #include +#if __has_include() +#include +namespace fs = std::filesystem; +#elif __has_include() +#include +namespace fs = std::experimental::filesystem; +#endif #include +#include #include #include #include @@ -222,6 +230,45 @@ void inferring_bluefs_devices(vector& devs, std::string& path) } } +static void bluefs_import( + const string& input_file, + const string& dest_file, + CephContext *cct, + const string& path, + const vector& devs) +{ + int r; + std::ifstream f(input_file.c_str(), std::ifstream::binary); + if (!f) { + r = -errno; + cerr << "open " << input_file.c_str() << " failed: " << cpp_strerror(r) << std::endl; + exit(EXIT_FAILURE); + } + + std::unique_ptr bs{open_bluefs_readonly(cct, path, devs)}; + + BlueFS::FileWriter *h; + fs::path file_path(dest_file); + const string dir = file_path.parent_path(); + const string file_name = file_path.filename(); + bs->open_for_write(dir, file_name, &h, false); + uint64_t max_block = 4096; + char buf[max_block]; + uint64_t left = fs::file_size(input_file.c_str()); + uint64_t size = 0; + while (left) { + size = std::min(max_block, left); + f.read(buf, size); + h->append(buf, size); + left -= size; + } + f.close(); + bs->fsync(h); + bs->close_writer(h); + bs->umount(); + return; +} + int main(int argc, char **argv) { string out_dir; @@ -231,6 +278,8 @@ int main(int argc, char **argv) string path; string action; string log_file; + string input_file; + string dest_file; string key, value; vector allocs_name; string empty_sharding(1, '\0'); @@ -243,6 +292,8 @@ int main(int argc, char **argv) ("help,h", "produce help message") ("path", po::value(&path), "bluestore path") ("out-dir", po::value(&out_dir), "output directory") + ("input-file", po::value(&input_file), "import file") + ("dest-file", po::value(&dest_file), "destination file") ("log-file,l", po::value(&log_file), "log file") ("log-level", po::value(&log_level), "log level (30=most, 20=lots, 10=some, 1=little)") ("dev", po::value>(&devs), "device(s)") @@ -262,6 +313,7 @@ int main(int argc, char **argv) "repair, " "quick-fix, " "bluefs-export, " + "bluefs-import, " "bluefs-bdev-sizes, " "bluefs-bdev-expand, " "bluefs-bdev-new-db, " @@ -348,7 +400,9 @@ int main(int argc, char **argv) if (devs.empty()) inferring_bluefs_devices(devs, path); } - if (action == "bluefs-export" || action == "bluefs-log-dump") { + if (action == "bluefs-export" || + action == "bluefs-import" || + action == "bluefs-log-dump") { if (path.empty()) { cerr << "must specify bluestore path" << std::endl; exit(EXIT_FAILURE); @@ -357,6 +411,14 @@ int main(int argc, char **argv) cerr << "must specify out-dir to export bluefs" << std::endl; exit(EXIT_FAILURE); } + if (action == "bluefs-import" && input_file.empty()) { + cerr << "must specify input_file to import bluefs" << std::endl; + exit(EXIT_FAILURE); + } + if (action == "bluefs-import" && dest_file.empty()) { + cerr << "must specify dest_file to import bluefs" << std::endl; + exit(EXIT_FAILURE); + } inferring_bluefs_devices(devs, path); } if (action == "bluefs-bdev-sizes" || action == "bluefs-bdev-expand") { @@ -600,6 +662,9 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } } + else if (action == "bluefs-import") { + bluefs_import(input_file, dest_file, cct.get(), path, devs); + } else if (action == "bluefs-export") { BlueFS *fs = open_bluefs_readonly(cct.get(), path, devs);