diff options
author | Sage Weil <sage@inktank.com> | 2013-08-15 11:01:35 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-15 11:01:35 -0700 |
commit | ea79bb2913f657a89455317c84d926d891104a35 (patch) | |
tree | bdb52f62902408055c78694ec6f16d5eb0ef240d | |
parent | 4422f21a6586467a63ce6841552d0f60aa849cf1 (diff) | |
parent | c81edf1ec9add504efbe787d9b850e56e6ff67cb (diff) | |
download | ceph-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.cc | 80 |
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; |