From 1e6c390a67b2500d5a934b6537b8c7e9e1f096c6 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 26 Apr 2013 16:47:53 -0700 Subject: [PATCH 1/3] tools: add ceph_monstore_tool with getosdmap Signed-off-by: Samuel Just --- src/Makefile.am | 7 ++ src/tools/ceph-monstore-tool.cc | 132 ++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 src/tools/ceph-monstore-tool.cc diff --git a/src/Makefile.am b/src/Makefile.am index c4e08ba1d79..476c80e8027 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -128,6 +128,13 @@ ceph_filestore_dump_LDADD += -ldl endif bin_PROGRAMS += ceph ceph-conf ceph-authtool ceph_filestore_dump +ceph_monstore_tool_SOURCES = tools/ceph-monstore-tool.cc \ + os/LevelDBStore.cc +ceph_monstore_tool_LDFLAGS = ${AM_LDFLAGS} +ceph_monstore_tool_LDADD = $(LIBOS_LDA) $(LIBGLOBAL_LDA) -lboost_program_options +ceph_monstore_tool_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +bin_PROGRAMS += ceph_monstore_tool + monmaptool_SOURCES = monmaptool.cc monmaptool_LDADD = $(LIBGLOBAL_LDA) crushtool_SOURCES = crushtool.cc diff --git a/src/tools/ceph-monstore-tool.cc b/src/tools/ceph-monstore-tool.cc new file mode 100644 index 00000000000..9b6a22afd02 --- /dev/null +++ b/src/tools/ceph-monstore-tool.cc @@ -0,0 +1,132 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 Inktank, Inc. +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "global/global_init.h" +#include "os/LevelDBStore.h" +#include "mon/MonitorDBStore.h" + +namespace po = boost::program_options; +using namespace std; + +int main(int argc, char **argv) { + po::options_description desc("Allowed options"); + int version = -1; + string store_path, cmd, out_path; + desc.add_options() + ("help", "produce help message") + ("mon-store-path", po::value(&store_path), + "path to mon directory, mandatory") + ("out", po::value(&out_path), + "out path") + ("version", po::value(&version), + "version requested") + ("command", po::value(&cmd), + "command") + ; + po::positional_options_description p; + p.add("command", 1); + p.add("version", 1); + + po::variables_map vm; + po::parsed_options parsed = + po::command_line_parser(argc, argv).options(desc).positional(p).run(); + po::store( + parsed, + vm); + try { + po::notify(vm); + } catch (...) { + cout << desc << std::endl; + return 1; + } + + vector ceph_options, def_args; + vector ceph_option_strings = po::collect_unrecognized( + parsed.options, po::include_positional); + ceph_options.reserve(ceph_option_strings.size()); + for (vector::iterator i = ceph_option_strings.begin(); + i != ceph_option_strings.end(); + ++i) { + ceph_options.push_back(i->c_str()); + } + + global_init( + &def_args, ceph_options, CEPH_ENTITY_TYPE_OSD, + CODE_ENVIRONMENT_UTILITY, 0); + common_init_finish(g_ceph_context); + g_ceph_context->_conf->apply_changes(NULL); + g_conf = g_ceph_context->_conf; + + if (vm.count("help")) { + std::cerr << desc << std::endl; + return 1; + } + + int fd; + if (vm.count("out")) { + fd = open(out_path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666); + } else { + fd = STDOUT_FILENO; + } + + MonitorDBStore st(store_path); + stringstream ss; + int r = st.open(ss); + if (r < 0) { + std::cerr << ss.str() << std::endl; + goto done; + } + if (cmd == "getosdmap") { + version_t v; + if (version == -1) { + v = st.get("osdmap", "last_committed"); + } else { + v = version; + } + + bufferlist bl; + /// XXX: this is not ok, osdmap and full should be abstracted somewhere + int r = st.get("osdmap", st.combine_strings("full", v), bl); + if (r < 0) { + std::cerr << "Error getting map: " << cpp_strerror(r) << std::endl; + goto done; + } + bl.write_fd(fd); + } else { + std::cerr << "Unrecognized command: " << cmd << std::endl; + goto done; + } + + done: + if (vm.count("out")) { + ::close(fd); + } + return 0; +} From e725c3e210b244e090d70c77d937c94f4f63a2be Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 26 Apr 2013 16:48:21 -0700 Subject: [PATCH 2/3] PaxosService: use get and put for version_t Otherwise, we just duplicate the logic for generating the version key names. Signed-off-by: Samuel Just --- src/mon/PaxosService.cc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/mon/PaxosService.cc b/src/mon/PaxosService.cc index 9484f367a6f..d02cb1d7ab5 100644 --- a/src/mon/PaxosService.cc +++ b/src/mon/PaxosService.cc @@ -294,19 +294,13 @@ void PaxosService::put_version(MonitorDBStore::Transaction *t, const string& prefix, version_t ver, bufferlist& bl) { - ostringstream os; - os << ver; - string key = mon->store->combine_strings(prefix, os.str()); - t->put(get_service_name(), key, bl); + t->put(get_service_name(), ver, bl); } int PaxosService::get_version(const string& prefix, version_t ver, bufferlist& bl) { - ostringstream os; - os << ver; - string key = mon->store->combine_strings(prefix, os.str()); - return mon->store->get(get_service_name(), key, bl); + return mon->store->get(get_service_name(), ver, bl); } void PaxosService::trim(MonitorDBStore::Transaction *t, From 79280d9f4e5d33ffd12499a2d30d8e0875e3351a Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 26 Apr 2013 17:16:53 -0700 Subject: [PATCH 3/3] OSDMonitor: when adding bucket, delay response if pending map has name Fixes: #4836 Signed-off-by: Samuel Just --- src/mon/OSDMonitor.cc | 47 ++++++++++++++++++++++++++++--------------- src/mon/OSDMonitor.h | 2 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index e8a277a7b01..d46c28f6ff2 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -58,6 +58,15 @@ static ostream& _prefix(std::ostream *_dout, Monitor *mon, OSDMap& osdmap) { << ").osd e" << osdmap.get_epoch() << " "; } +bool OSDMonitor::_have_pending_crush() +{ + return pending_inc.crush.length(); +} + +CrushWrapper &OSDMonitor::_get_stable_crush() +{ + return *osdmap.crush; +} void OSDMonitor::_get_pending_crush(CrushWrapper& newcrush) { @@ -2534,27 +2543,33 @@ bool OSDMonitor::prepare_command(MMonCommand *m) else if (m->cmd.size() == 5 && m->cmd[1] == "crush" && (m->cmd[2] == "add-bucket")) { do { // osd crush add-bucket - CrushWrapper newcrush; - _get_pending_crush(newcrush); - - if (newcrush.name_exists(m->cmd[3])) { + if (!_have_pending_crush() && + _get_stable_crush().name_exists(m->cmd[3])) { ss << "bucket '" << m->cmd[3] << "' already exists"; err = 0; break; } - int type = newcrush.get_type_id(m->cmd[4]); - if (type <= 0) { - ss << "type '" << m->cmd[4] << "' does not exist"; - err = -EINVAL; - break; - } - int bucketno = newcrush.add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_DEFAULT, - type, 0, NULL, NULL); - newcrush.set_item_name(bucketno, m->cmd[3]); - pending_inc.crush.clear(); - newcrush.encode(pending_inc.crush); - ss << "added bucket " << m->cmd[3] << " type " << m->cmd[4] << " to crush map"; + CrushWrapper newcrush; + _get_pending_crush(newcrush); + if (newcrush.name_exists(m->cmd[3])) { + ss << "bucket '" << m->cmd[3] << "' already exists"; + err = 0; + } else { + int type = newcrush.get_type_id(m->cmd[4]); + if (type <= 0) { + ss << "type '" << m->cmd[4] << "' does not exist"; + err = -EINVAL; + break; + } + int bucketno = newcrush.add_bucket(0, CRUSH_BUCKET_STRAW, CRUSH_HASH_DEFAULT, + type, 0, NULL, NULL); + newcrush.set_item_name(bucketno, m->cmd[3]); + + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush); + ss << "added bucket " << m->cmd[3] << " type " << m->cmd[4] << " to crush map"; + } getline(ss, rs); wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs, get_version())); return true; diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h index 0034bb0baca..30fd09fa499 100644 --- a/src/mon/OSDMonitor.h +++ b/src/mon/OSDMonitor.h @@ -137,6 +137,8 @@ private: int thrash_last_up_osd; bool thrash(); + bool _have_pending_crush(); + CrushWrapper &_get_stable_crush(); void _get_pending_crush(CrushWrapper& newcrush); // svc