]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-bluestore-tool: clean up usage and bluefs-export command
authorSage Weil <sage@redhat.com>
Thu, 30 Mar 2017 19:45:17 +0000 (15:45 -0400)
committerSage Weil <sage@redhat.com>
Thu, 30 Mar 2017 19:45:17 +0000 (15:45 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.h
src/os/bluestore/bluestore_tool.cc

index fca4e20f2a42d8bb18585e63a92c4d986dc7f942..99e7570bb42f280287cc9d32c73c79bed323a43c 100644 (file)
@@ -1858,8 +1858,10 @@ private:
                                   bool create);
 
   int _write_bdev_label(string path, bluestore_bdev_label_t label);
+public:
   static int _read_bdev_label(CephContext* cct, string path,
                              bluestore_bdev_label_t *label);
+private:
   int _check_or_set_bdev_label(string path, uint64_t size, string desc,
                               bool create);
 
index dc7812367b5e872e76a2c6e091fd5a704bb664fe..7ae4fd6b1bc816a2f02aee4ec12859ad3cf792c4 100644 (file)
@@ -1,6 +1,9 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+
 #include <stdio.h>
 #include <string.h>
 #include <iostream>
 #include "common/errno.h"
 
 #include "os/bluestore/BlueFS.h"
+#include "os/bluestore/BlueStore.h"
+
+namespace po = boost::program_options;
 
-void usage(char **argv)
+void usage(po::options_description &desc)
 {
-  cout << argv[0] << " <outdir> <bdev[0..2]>" << std::endl;;
+  cout << desc << std::endl;
 }
 
 int main(int argc, char **argv)
 {
+  string out_dir;
+  vector<string> devs;
+  string action;
+  po::options_description po_options("Options");
+  po_options.add_options()
+    ("help,h", "produce help message")
+    ("out-dir", po::value<string>(&out_dir), "output directory")
+    ("dev", po::value<vector<string>>(&devs), "device(s)")
+    ;
+  po::options_description po_positional("Positional options");
+  po_positional.add_options()
+    ("command", po::value<string>(&action), "show-label, bluefs-export")
+    ;
+  po::options_description po_all("All options");
+  po_all.add(po_options).add(po_positional);
+  po::positional_options_description pd;
+  pd.add("command", 1);
+
+  vector<string> ceph_option_strings;
+  po::variables_map vm;
+  try {
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(po_all).allow_unregistered().positional(pd).run();
+    po::store( parsed, vm);
+    po::notify(vm);
+    ceph_option_strings = po::collect_unrecognized(parsed.options,
+                                                  po::include_positional);
+  } catch(po::error &e) {
+    std::cerr << e.what() << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help")) {
+    usage(po_all);
+    return 1;
+  }
+  if (action.empty()) {
+    cerr << "must specify an action; --help for help" << std::endl;
+    return 1;
+  }
+
+  if (devs.empty()) {
+    cerr << "must specify one or more device(s)" << std::endl;
+    exit(1);
+  }
+
   vector<const char*> args;
-  argv_to_vec(argc, (const char **)argv, args);
+  for (auto& i : ceph_option_strings) {
+    args.push_back(i.c_str());
+  }
   env_to_vec(args);
 
   auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
                         CODE_ENVIRONMENT_UTILITY, 0);
   common_init_finish(cct.get());
-  cct->_conf->set_val(
-    "enable_experimental_unrecoverable_data_corrupting_features",
-    "*");
-  cct->_conf->apply_changes(NULL);
 
-  BlueFS fs(&(*cct));
+  cout << "action " << action << std::endl;
 
-  if (args.size() != 4) {
-    usage(argv);
-    exit(-1);
+  if (action == "show-label") {
+    JSONFormatter jf(true);
+    jf.open_array_section("devices");
+    for (auto& i : devs) {
+      bluestore_bdev_label_t label;
+      int r = BlueStore::_read_bdev_label(cct.get(), i, &label);
+      if (r < 0) {
+       cerr << "unable to read label for " << i << ": "
+            << cpp_strerror(r) << std::endl;
+       exit(1);
+      }
+      jf.open_object_section(i.c_str());
+      label.dump(&jf);
+      jf.close_section();
+    }
+    jf.close_section();
+    jf.flush(cout);
   }
+  if (action == "bluefs-export") {
+    if (out_dir.empty()) {
+      cerr << "must specify out-dir to export bluefs" << std::endl;
+      exit(1);
+    }
+    BlueFS fs(&(*cct));
+    string main;
+    set<int> got;
+    for (auto& i : devs) {
+      bluestore_bdev_label_t label;
+      int r = BlueStore::_read_bdev_label(cct.get(), i, &label);
+      if (r < 0) {
+       cerr << "unable to read label for " << i << ": "
+            << cpp_strerror(r) << std::endl;
+       exit(1);
+      }
+      int id = -1;
+      if (label.description == "main")
+       main = i;
+      else if (label.description == "bluefs db")
+       id = BlueFS::BDEV_DB;
+      else if (label.description == "bluefs wal")
+       id = BlueFS::BDEV_WAL;
+      if (id >= 0) {
+       got.insert(id);
+       cout << " slot " << id << " " << i << std::endl;
+       int r = fs.add_block_device(id, i);
+       if (r < 0) {
+         cerr << "unable to open " << i << ": " << cpp_strerror(r) << std::endl;
+         exit(1);
+       }
+      }
+    }
+    if (main.length()) {
+      int id = BlueFS::BDEV_DB;
+      if (got.count(BlueFS::BDEV_DB))
+       id = BlueFS::BDEV_SLOW;
+      cout << " slot " << id << " " << main << std::endl;
+      int r = fs.add_block_device(id, main);
+      if (r < 0) {
+       cerr << "unable to open " << main << ": " << cpp_strerror(r)
+            << std::endl;
+       exit(1);
+      }
+    }
 
-  cout << "args " << args << std::endl;
-  string outdir = args[0];
-  for (unsigned i = 1; i < args.size(); ++i) {
-    fs.add_block_device(i-1, args[i]);
-  }
+    int r = fs.mount();
+    if (r < 0) {
+      cerr << "unable to mount bluefs: " << cpp_strerror(r)
+          << std::endl;
+      exit(1);
+    }
 
-  int r = fs.mount();
-  assert(r == 0);
-
-  vector<string> dirs;
-  r = fs.readdir("", &dirs);
-  assert(r == 0);
-  for (auto& dir : dirs) {
-    if (dir[0] == '.')
-      continue;
-    cout << dir << "/" << std::endl;
-    vector<string> ls;
-    r = fs.readdir(dir, &ls);
+    vector<string> dirs;
+    r = fs.readdir("", &dirs);
     assert(r == 0);
-    string cmd = "mkdir -p " + outdir + "/" + dir;
-    r = system(cmd.c_str());
-    assert(r == 0);
-    for (auto& file : ls) {
-      if (file[0] == '.')
+    for (auto& dir : dirs) {
+      if (dir[0] == '.')
        continue;
-      cout << dir << "/" << file << std::endl;
-      uint64_t size;
-      utime_t mtime;
-      r = fs.stat(dir, file, &size, &mtime);
+      cout << dir << "/" << std::endl;
+      vector<string> ls;
+      r = fs.readdir(dir, &ls);
+      assert(r == 0);
+      string full = out_dir + "/" + dir;
+      r = ::mkdir(full.c_str(), 0755);
       assert(r == 0);
-      string path = outdir + "/" + dir + "/" + file;
-      int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644);
-      assert(fd >= 0);
-      if (size > 0) {
-       BlueFS::FileReader *h;
-       r = fs.open_for_read(dir, file, &h, false);
+      for (auto& file : ls) {
+       if (file[0] == '.')
+         continue;
+       cout << dir << "/" << file << std::endl;
+       uint64_t size;
+       utime_t mtime;
+       r = fs.stat(dir, file, &size, &mtime);
        assert(r == 0);
-       int pos = 0;
-       int left = size;
-       while (left) {
-         bufferlist bl;
-         r = fs.read(h, &h->buf, pos, left, &bl, NULL);
-         assert(r > 0);
-         int rc = bl.write_fd(fd);
-         assert(rc == 0);
-         pos += r;
-         left -= r;
+       string path = out_dir + "/" + dir + "/" + file;
+       int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644);
+       assert(fd >= 0);
+       if (size > 0) {
+         BlueFS::FileReader *h;
+         r = fs.open_for_read(dir, file, &h, false);
+         assert(r == 0);
+         int pos = 0;
+         int left = size;
+         while (left) {
+           bufferlist bl;
+           r = fs.read(h, &h->buf, pos, left, &bl, NULL);
+           assert(r > 0);
+           int rc = bl.write_fd(fd);
+           assert(rc == 0);
+           pos += r;
+           left -= r;
+         }
+         delete h;
        }
-       delete h;
+       ::close(fd);
       }
-      ::close(fd);
     }
+    fs.umount();
   }
+
+  return 0;
 }