]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/bluestore_tool: add sanity check before exporting bluefs
authorxie xingguo <xie.xingguo@zte.com.cn>
Thu, 29 Jun 2017 03:44:40 +0000 (11:44 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Thu, 29 Jun 2017 06:59:52 +0000 (14:59 +0800)
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 <xie.xingguo@zte.com.cn>
src/os/bluestore/bluestore_tool.cc

index 29863db679e173f4d6cb55078999110552cc888d..d6ca7c2b19cd87aa1045b7f8efa0847a517764a3 100644 (file)
@@ -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<const char*> 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<int> got;