From: xie xingguo Date: Thu, 29 Jun 2017 03:44:40 +0000 (+0800) Subject: os/bluestore/bluestore_tool: add sanity check before exporting bluefs X-Git-Tag: v12.1.2~100^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b96d7864b7c2139fe625b87097ac10db7c0bd112;p=ceph.git os/bluestore/bluestore_tool: add sanity check before exporting bluefs This can prevent crash by directly specifying a bluestore dev, as follow: ---------------------------------------------------------------------------------- ./bin/ceph-bluestore-tool --dev ./dev/osd1/block bluefs-export --out /clove/vm/xxg /clove/vm/xxg/build/ceph/src/os/bluestore/bluefs_types.h: In function 'static void bluefs_fnode_t::_denc_finish(ceph::buffer::ptr::iterator&, __u8*, __u8*, char**, uint32_t*)' thread 7fd4311d0b80 time 2017-06-29 14:59:20.376224 /clove/vm/xxg/build/ceph/src/os/bluestore/bluefs_types.h: 54: FAILED assert(pos <= end) ceph version 12.0.3-2356-g9f77a53 (9f77a53e00522bfa193e7e0847a2aebfa7648761) luminous (dev) ---------------------------------------------------------------------------------- The cure is that we require caller pass in path for bluefs-export command instead, and bluestore will be smart enough to detect the bluefs devices from that. Also we add some sanity check to detect errors earlier here. Signed-off-by: xie xingguo --- diff --git a/src/os/bluestore/bluestore_tool.cc b/src/os/bluestore/bluestore_tool.cc index 29863db679e..d6ca7c2b19c 100644 --- a/src/os/bluestore/bluestore_tool.cc +++ b/src/os/bluestore/bluestore_tool.cc @@ -25,6 +25,46 @@ void usage(po::options_description &desc) cout << desc << std::endl; } +void validate_path(CephContext *cct, const string& path, bool bluefs) +{ + BlueStore bluestore(cct, path); + string type; + int r = bluestore.read_meta("type", &type); + if (r < 0) { + cerr << "failed to load os-type: " << cpp_strerror(r) << std::endl; + exit(EXIT_FAILURE); + } + if (type != "bluestore") { + cerr << "expected bluestore, but type is " << type << std::endl; + exit(EXIT_FAILURE); + } + if (!bluefs) { + return; + } + + string kv_backend; + r = bluestore.read_meta("kv_backend", &kv_backend); + if (r < 0) { + cerr << "failed to load kv_backend: " << cpp_strerror(r) << std::endl; + exit(EXIT_FAILURE); + } + if (kv_backend != "rocksdb") { + cerr << "expect kv_backend to be rocksdb, but is " << kv_backend + << std::endl; + exit(EXIT_FAILURE); + } + string bluefs_enabled; + r = bluestore.read_meta("bluefs", &bluefs_enabled); + if (r < 0) { + cerr << "failed to load do_bluefs: " << cpp_strerror(r) << std::endl; + exit(EXIT_FAILURE); + } + if (bluefs_enabled != "1") { + cerr << "bluefs not enabled for rocksdb" << std::endl; + exit(EXIT_FAILURE); + } +} + int main(int argc, char **argv) { string out_dir; @@ -78,8 +118,7 @@ int main(int argc, char **argv) exit(1); } } - if (action == "bluefs-export" || - action == "show-label") { + if (action == "show-label") { if (devs.empty() && path.empty()) { cerr << "must specify bluestore path *or* raw device(s)" << std::endl; exit(1); @@ -93,6 +132,24 @@ int main(int argc, char **argv) } } } + if (action == "bluefs-export") { + if (path.empty()) { + cerr << "must specify bluestore path" << std::endl; + exit(EXIT_FAILURE); + } + if (out_dir.empty()) { + cerr << "must specify out-dir to export bluefs" << std::endl; + exit(EXIT_FAILURE); + } + cout << "infering bluefs devices from bluestore path" << std::endl; + for (auto fn : {"block", "block.wal", "block.db"}) { + string p = path + "/" + fn; + struct stat st; + if (::stat(p.c_str(), &st) == 0) { + devs.push_back(p); + } + } + } vector args; for (auto& i : ceph_option_strings) { @@ -108,6 +165,7 @@ int main(int argc, char **argv) if (action == "fsck" || action == "fsck-deep") { + validate_path(cct.get(), path, false); BlueStore bluestore(cct.get(), path); int r = bluestore.fsck(fsck_deep); if (r < 0) { @@ -134,10 +192,7 @@ int main(int argc, char **argv) jf.flush(cout); } else if (action == "bluefs-export") { - if (out_dir.empty()) { - cerr << "must specify out-dir to export bluefs" << std::endl; - exit(1); - } + validate_path(cct.get(), path, true); BlueFS fs(&(*cct)); string main; set got;