summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-15 11:01:35 -0700
committerSage Weil <sage@inktank.com>2013-08-15 11:01:35 -0700
commitea79bb2913f657a89455317c84d926d891104a35 (patch)
treebdb52f62902408055c78694ec6f16d5eb0ef240d
parent4422f21a6586467a63ce6841552d0f60aa849cf1 (diff)
parentc81edf1ec9add504efbe787d9b850e56e6ff67cb (diff)
downloadceph-ea79bb2913f657a89455317c84d926d891104a35.tar.gz
Merge pull request #496 from ceph/wip-monstore-copy
tools: ceph-monstore-tool: copy a store's contents to another store
-rw-r--r--src/tools/ceph-monstore-tool.cc80
1 files changed, 77 insertions, 3 deletions
diff --git a/src/tools/ceph-monstore-tool.cc b/src/tools/ceph-monstore-tool.cc
index f361266aff0..4ab8fa86465 100644
--- a/src/tools/ceph-monstore-tool.cc
+++ b/src/tools/ceph-monstore-tool.cc
@@ -33,6 +33,7 @@
#include "mon/MonitorDBStore.h"
#include "mon/Paxos.h"
#include "common/Formatter.h"
+#include "include/stringify.h"
namespace po = boost::program_options;
using namespace std;
@@ -180,13 +181,20 @@ int main(int argc, char **argv) {
if (vm.count("out")) {
if ((fd = open(out_path.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) {
int _err = errno;
- std::cerr << "Couldn't open " << out_path << cpp_strerror(_err) << std::endl;
- return 1;
+ if (_err != EISDIR) {
+ std::cerr << "Couldn't open " << out_path << ": " << cpp_strerror(_err) << std::endl;
+ return 1;
+ }
}
} else {
fd = STDOUT_FILENO;
}
+ if (fd < 0 && cmd != "store-copy") {
+ std::cerr << "error: '" << out_path << "' is a directory!" << std::endl;
+ return 1;
+ }
+
MonitorDBStore st(store_path);
if (store_path.size()) {
stringstream ss;
@@ -331,13 +339,79 @@ int main(int argc, char **argv) {
t.compact_prefix(prefix);
st.apply_transaction(t);
}
+ } else if (cmd == "store-copy") {
+ if (!store_path.size()) {
+ std::cerr << "need mon store path to copy from" << std::endl;
+ std::cerr << desc << std::endl;
+ goto done;
+ }
+ if (!out_path.size()) {
+ std::cerr << "need mon store path to copy to (--out <mon_data_dir>)"
+ << std::endl;
+ std::cerr << desc << std::endl;
+ goto done;
+ }
+ if (fd > 0) {
+ std::cerr << "supplied out path '" << out_path << "' is not a directory"
+ << std::endl;
+ goto done;
+ }
+
+ MonitorDBStore out_store(out_path);
+ {
+ stringstream ss;
+ int r = out_store.create_and_open(ss);
+ if (r < 0) {
+ std::cerr << ss.str() << std::endl;
+ goto done;
+ }
+ }
+
+
+ KeyValueDB::WholeSpaceIterator it = st.get_iterator();
+ uint64_t total_keys = 0;
+ uint64_t total_size = 0;
+ uint64_t total_tx = 0;
+
+ do {
+ uint64_t num_keys = 0;
+
+ MonitorDBStore::Transaction tx;
+
+ while (it->valid() && num_keys < 128) {
+ pair<string,string> k = it->raw_key();
+ bufferlist v = it->value();
+ tx.put(k.first, k.second, v);
+
+ num_keys ++;
+ total_tx ++;
+ total_size += v.length();
+
+ it->next();
+ }
+
+ total_keys += num_keys;
+
+ if (!tx.empty())
+ out_store.apply_transaction(tx);
+
+ std::cout << "copied " << total_keys << " keys so far ("
+ << stringify(si_t(total_size)) << ")" << std::endl;
+
+ } while (it->valid());
+
+ std::cout << "summary: copied " << total_keys << " keys, using "
+ << total_tx << " transactions, totalling "
+ << stringify(si_t(total_size)) << std::endl;
+ std::cout << "from '" << store_path << "' to '" << out_path << "'"
+ << std::endl;
} else {
std::cerr << "Unrecognized command: " << cmd << std::endl;
goto done;
}
done:
- if (vm.count("out")) {
+ if (vm.count("out") && fd > 0) {
::close(fd);
}
return 0;