X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fos%2Fbluestore%2Fbluestore_tool.cc;fp=src%2Fceph%2Fsrc%2Fos%2Fbluestore%2Fbluestore_tool.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=db55868692e4c68bb4cb8b669fd642715d89fda7;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/os/bluestore/bluestore_tool.cc b/src/ceph/src/os/bluestore/bluestore_tool.cc deleted file mode 100644 index db55868..0000000 --- a/src/ceph/src/os/bluestore/bluestore_tool.cc +++ /dev/null @@ -1,541 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include -#include - -#include -#include -#include -#include -#include -#include -#include "global/global_init.h" -#include "common/ceph_argparse.h" -#include "include/stringify.h" -#include "common/errno.h" -#include "common/safe_io.h" - -#include "os/bluestore/BlueFS.h" -#include "os/bluestore/BlueStore.h" - -namespace po = boost::program_options; - -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); - } -} - -BlueFS *open_bluefs( - CephContext *cct, - const string& path, - const vector& devs) -{ - validate_path(cct, path, true); - BlueFS *fs = new BlueFS(cct); - - string main; - set got; - for (auto& i : devs) { - bluestore_bdev_label_t label; - int r = BlueStore::_read_bdev_label(cct, i, &label); - if (r < 0) { - cerr << "unable to read label for " << i << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - 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(EXIT_FAILURE); - } - } - } - 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(EXIT_FAILURE); - } - } - - int r = fs->mount(); - if (r < 0) { - cerr << "unable to mount bluefs: " << cpp_strerror(r) - << std::endl; - exit(EXIT_FAILURE); - } - return fs; -} - -int main(int argc, char **argv) -{ - string out_dir; - vector devs; - string path; - string action; - string log_file; - string key, value; - int log_level = 30; - bool fsck_deep = false; - po::options_description po_options("Options"); - po_options.add_options() - ("help,h", "produce help message") - ("path", po::value(&path), "bluestore path") - ("out-dir", po::value(&out_dir), "output directory") - ("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)") - ("deep", po::value(&fsck_deep), "deep fsck (read all data)") - ("key,k", po::value(&key), "label metadata key name") - ("value,v", po::value(&value), "label metadata value") - ; - po::options_description po_positional("Positional options"); - po_positional.add_options() - ("command", po::value(&action), "fsck, repair, bluefs-export, bluefs-bdev-sizes, bluefs-bdev-expand, show-label, set-label-key, rm-label-key, prime-osd-dir") - ; - 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 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; - exit(EXIT_FAILURE); - } - - if (vm.count("help")) { - usage(po_all); - exit(EXIT_SUCCESS); - } - if (action.empty()) { - cerr << "must specify an action; --help for help" << std::endl; - exit(EXIT_FAILURE); - } - - if (action == "fsck" || action == "repair") { - if (path.empty()) { - cerr << "must specify bluestore path" << std::endl; - exit(EXIT_FAILURE); - } - } - if (action == "prime-osd-dir") { - if (devs.size() != 1) { - cerr << "must specify the main bluestore device" << std::endl; - exit(EXIT_FAILURE); - } - if (path.empty()) { - cerr << "must specify osd dir to prime" << std::endl; - exit(EXIT_FAILURE); - } - } - if (action == "set-label-key" || - action == "rm-label-key") { - if (devs.size() != 1) { - cerr << "must specify the main bluestore device" << std::endl; - exit(EXIT_FAILURE); - } - if (key.size() == 0) { - cerr << "must specify a key name with -k" << std::endl; - exit(EXIT_FAILURE); - } - if (action == "set-label-key" && value.size() == 0) { - cerr << "must specify a value with -v" << std::endl; - exit(EXIT_FAILURE); - } - } - if (action == "show-label") { - if (devs.empty() && path.empty()) { - cerr << "must specify bluestore path *or* raw device(s)" << std::endl; - exit(EXIT_FAILURE); - } - if (devs.empty()) { - 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); - } - } - } - } - 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); - } - } - } - if (action == "bluefs-bdev-sizes" || action == "bluefs-bdev-expand") { - if (path.empty()) { - cerr << "must specify bluestore path" << 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; - if (log_file.size()) { - args.push_back("--log-file"); - args.push_back(log_file.c_str()); - static char ll[10]; - snprintf(ll, sizeof(ll), "%d", log_level); - args.push_back("--debug-bluestore"); - args.push_back(ll); - args.push_back("--debug-bluefs"); - args.push_back(ll); - } - args.push_back("--no-log-to-stderr"); - args.push_back("--err-to-stderr"); - - 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()); - - if (action == "fsck" || - action == "repair") { - validate_path(cct.get(), path, false); - BlueStore bluestore(cct.get(), path); - int r; - if (action == "fsck") { - r = bluestore.fsck(fsck_deep); - } else { - r = bluestore.repair(fsck_deep); - } - if (r < 0) { - cerr << "error from fsck: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - cout << action << " success" << std::endl; - } - else if (action == "prime-osd-dir") { - bluestore_bdev_label_t label; - int r = BlueStore::_read_bdev_label(cct.get(), devs.front(), &label); - if (r < 0) { - cerr << "failed to read label for " << devs.front() << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - - // kludge some things into the map that we want to populate into - // target dir - label.meta["path_block"] = devs.front(); - label.meta["type"] = "bluestore"; - label.meta["fsid"] = stringify(label.osd_uuid); - - for (auto kk : { - "whoami", - "osd_key", - "path_block", "path_block.db", "path_block.wal", - "ceph_fsid", - "fsid", - "type", - "ready" }) { - string k = kk; - auto i = label.meta.find(k); - if (i == label.meta.end()) { - continue; - } - string p = path + "/" + k; - string v = i->second; - if (k == "osd_key") { - p = path + "/keyring"; - v = "[osd."; - v += label.meta["whoami"]; - v += "]\nkey = " + i->second; - } - if (k.find("path_") == 0) { - p = path + "/" + k.substr(5); - int r = ::symlink(v.c_str(), p.c_str()); - if (r < 0 && errno == EEXIST) { - struct stat st; - r = ::stat(p.c_str(), &st); - if (r == 0 && S_ISLNK(st.st_mode)) { - char target[PATH_MAX]; - r = ::readlink(p.c_str(), target, sizeof(target)); - if (r > 0) { - if (v == target) { - r = 0; // already matches our target - } else { - ::unlink(p.c_str()); - r = ::symlink(v.c_str(), p.c_str()); - } - } else { - cerr << "error reading existing link at " << p << ": " << cpp_strerror(errno) - << std::endl; - } - } - } - if (r < 0) { - cerr << "error symlinking " << p << ": " << cpp_strerror(errno) - << std::endl; - exit(EXIT_FAILURE); - } - } else { - v += "\n"; - int fd = ::open(p.c_str(), O_CREAT|O_TRUNC|O_WRONLY, 0600); - if (fd < 0) { - cerr << "error writing " << p << ": " << cpp_strerror(errno) - << std::endl; - exit(EXIT_FAILURE); - } - int r = safe_write(fd, v.c_str(), v.size()); - if (r < 0) { - cerr << "error writing to " << p << ": " << cpp_strerror(errno) - << std::endl; - exit(EXIT_FAILURE); - } - ::close(fd); - } - } - } - else if (action == "show-label") { - JSONFormatter jf(true); - jf.open_object_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(EXIT_FAILURE); - } - jf.open_object_section(i.c_str()); - label.dump(&jf); - jf.close_section(); - } - jf.close_section(); - jf.flush(cout); - } - else if (action == "set-label-key") { - bluestore_bdev_label_t label; - int r = BlueStore::_read_bdev_label(cct.get(), devs.front(), &label); - if (r < 0) { - cerr << "unable to read label for " << devs.front() << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - label.meta[key] = value; - r = BlueStore::_write_bdev_label(cct.get(), devs.front(), label); - if (r < 0) { - cerr << "unable to write label for " << devs.front() << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - } - else if (action == "rm-label-key") { - bluestore_bdev_label_t label; - int r = BlueStore::_read_bdev_label(cct.get(), devs.front(), &label); - if (r < 0) { - cerr << "unable to read label for " << devs.front() << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - if (!label.meta.count(key)) { - cerr << "key '" << key << "' not present" << std::endl; - exit(EXIT_FAILURE); - } - label.meta.erase(key); - r = BlueStore::_write_bdev_label(cct.get(), devs.front(), label); - if (r < 0) { - cerr << "unable to write label for " << devs.front() << ": " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - } - else if (action == "bluefs-bdev-sizes") { - BlueFS *fs = open_bluefs(cct.get(), path, devs); - fs->dump_block_extents(cout); - delete fs; - } - else if (action == "bluefs-bdev-expand") { - BlueFS *fs = open_bluefs(cct.get(), path, devs); - cout << "start:" << std::endl; - fs->dump_block_extents(cout); - for (int devid : { BlueFS::BDEV_WAL, BlueFS::BDEV_DB }) { - interval_set before; - fs->get_block_extents(devid, &before); - uint64_t end = before.range_end(); - uint64_t size = fs->get_block_device_size(devid); - if (end < size) { - cout << "expanding dev " << devid << " from 0x" << std::hex - << end << " to 0x" << size << std::dec << std::endl; - fs->add_block_extent(devid, end, size-end); - } - } - delete fs; - } - else if (action == "bluefs-export") { - BlueFS *fs = open_bluefs(cct.get(), path, devs); - - vector dirs; - int r = fs->readdir("", &dirs); - if (r < 0) { - cerr << "readdir in root failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - for (auto& dir : dirs) { - if (dir[0] == '.') - continue; - cout << dir << "/" << std::endl; - vector ls; - r = fs->readdir(dir, &ls); - if (r < 0) { - cerr << "readdir " << dir << " failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - string full = out_dir + "/" + dir; - r = ::mkdir(full.c_str(), 0755); - if (r < 0) { - r = -errno; - cerr << "mkdir " << full << " failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - 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); - if (r < 0) { - cerr << "stat " << file << " failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - string path = out_dir + "/" + dir + "/" + file; - int fd = ::open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644); - if (fd < 0) { - r = -errno; - cerr << "open " << path << " failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - assert(fd >= 0); - if (size > 0) { - BlueFS::FileReader *h; - r = fs->open_for_read(dir, file, &h, false); - if (r < 0) { - cerr << "open_for_read " << dir << "/" << file << " failed: " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - int pos = 0; - int left = size; - while (left) { - bufferlist bl; - r = fs->read(h, &h->buf, pos, left, &bl, NULL); - if (r <= 0) { - cerr << "read " << dir << "/" << file << " from " << pos - << " failed: " << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - int rc = bl.write_fd(fd); - if (rc < 0) { - cerr << "write to " << path << " failed: " - << cpp_strerror(r) << std::endl; - exit(EXIT_FAILURE); - } - pos += r; - left -= r; - } - delete h; - } - ::close(fd); - } - } - fs->umount(); - delete fs; - } else { - cerr << "unrecognized action " << action << std::endl; - return 1; - } - - return 0; -}