From d40825377ed440ea4881526a000ea3e8dca72d17 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 16 Mar 2017 15:09:26 -0400 Subject: [PATCH] osdmaptool: add --remap to run the remap_pgs() method Output ceph cli commands to realize the new remaps entries. Signed-off-by: Sage Weil --- src/tools/osdmaptool.cc | 114 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) diff --git a/src/tools/osdmaptool.cc b/src/tools/osdmaptool.cc index cc93561516435..db1480189d750 100644 --- a/src/tools/osdmaptool.cc +++ b/src/tools/osdmaptool.cc @@ -17,6 +17,7 @@ #include "common/ceph_argparse.h" #include "common/errno.h" +#include "common/safe_io.h" #include "global/global_init.h" #include "osd/OSDMap.h" @@ -37,9 +38,48 @@ void usage() cout << " --test-map-pg map a pgid to osds" << std::endl; cout << " --test-map-object [--pool ] map an object to osds" << std::endl; + cout << " --remap-cleanup clean up pg_remap[_items] entries, writing" << std::endl; + cout << " commands to [default: - for stdout]" << std::endl; + cout << " --remap calculate pg remap entries to balance pg layout" << std::endl; + cout << " writing commands to [default: - for stdout]" << std::endl; + cout << " --remap-max set max remap entries to calculate [default: 100]" << std::endl; + cout << " --remap-deviation " << std::endl; + cout << " max deviation from target [default: .01]" << std::endl; + cout << " --remap-pool restrict remap balancing to 1 or more pools" << std::endl; exit(1); } +void print_inc_remaps(const OSDMap::Incremental& pending_inc, int fd) +{ + ostringstream ss; + for (auto& i : pending_inc.old_pg_remap) { + ss << "ceph osd rm-pg-remap " << i << std::endl; + } + for (auto& i : pending_inc.new_pg_remap) { + ss << "ceph osd pg-remap " << i.first; + for (auto osd : i.second) { + ss << " " << osd; + } + ss << std::endl; + } + for (auto& i : pending_inc.old_pg_remap_items) { + ss << "ceph osd rm-pg-remap-items " << i << std::endl; + } + for (auto& i : pending_inc.new_pg_remap_items) { + ss << "ceph osd pg-remap-items " << i.first; + for (auto p : i.second) { + ss << " " << p.first << " " << p.second; + } + ss << std::endl; + } + string s = ss.str(); + int r = safe_write(fd, s.c_str(), s.size()); + if (r < 0) { + cerr << "error writing output: " << cpp_strerror(r) << std::endl; + exit(1); + } +} + int main(int argc, const char **argv) { vector args; @@ -75,6 +115,12 @@ int main(int argc, const char **argv) bool test_map_pgs = false; bool test_map_pgs_dump = false; bool test_random = false; + bool remap_cleanup = false; + bool remap = false; + std::string remap_file = "-"; + int remap_max = 100; + float remap_deviation = .01; + std::set remap_pools; int64_t pg_num = -1; bool test_map_pgs_dump_all = false; @@ -97,6 +143,15 @@ int main(int argc, const char **argv) if (!val.empty() && val != "plain") { tree_formatter.reset(Formatter::create(val, "", "json")); } + } else if (ceph_argparse_witharg(args, i, &remap_file, "--remap-cleanup", (char*)NULL)) { + remap_cleanup = true; + } else if (ceph_argparse_witharg(args, i, &remap_file, "--remap", (char*)NULL)) { + remap_cleanup = true; + remap = true; + } else if (ceph_argparse_witharg(args, i, &remap_max, err, "--remap-max", (char*)NULL)) { + } else if (ceph_argparse_witharg(args, i, &remap_deviation, err, "--remap-deviation", (char*)NULL)) { + } else if (ceph_argparse_witharg(args, i, &val, "--remap-pool", (char*)NULL)) { + remap_pools.insert(val); } else if (ceph_argparse_witharg(args, i, &num_osd, err, "--createsimple", (char*)NULL)) { if (!err.str().empty()) { cerr << err.str() << std::endl; @@ -248,6 +303,62 @@ int main(int argc, const char **argv) cout << "clearing pg/primary temp" << std::endl; osdmap.clear_temp(); } + int remap_fd = STDOUT_FILENO; + if (remap || remap_cleanup) { + if (remap_file != "-") { + remap_fd = ::open(remap_file.c_str(), O_CREAT|O_WRONLY, 0644); + if (remap_fd < 0) { + cerr << "error opening " << remap_file << ": " << cpp_strerror(errno) + << std::endl; + exit(1); + } + cout << "writing remap command output to: " << remap_file << std::endl; + } + } + if (remap_cleanup) { + cout << "checking for remap cleanups" << std::endl; + OSDMap::Incremental pending_inc(osdmap.get_epoch()+1); + pending_inc.fsid = osdmap.get_fsid(); + int r = osdmap.clean_remaps(g_ceph_context, &pending_inc); + if (r > 0) { + print_inc_remaps(pending_inc, remap_fd); + r = osdmap.apply_incremental(pending_inc); + assert(r == 0); + } + } + if (remap) { + cout << "remap, max-count " << remap_max + << ", max deviation " << remap_deviation + << std::endl; + OSDMap::Incremental pending_inc(osdmap.get_epoch()+1); + pending_inc.fsid = osdmap.get_fsid(); + set pools; + for (auto& s : remap_pools) { + int64_t p = osdmap.lookup_pg_pool_name(s); + if (p < 0) { + cerr << " pool '" << s << "' does not exist" << std::endl; + exit(1); + } + pools.insert(p); + } + if (!pools.empty()) + cout << " limiting to pools " << remap_pools << " (" << pools << ")" + << std::endl; + int changed = osdmap.remap_pgs(g_ceph_context, remap_deviation, + remap_max, pools, + &pending_inc); + if (changed) { + print_inc_remaps(pending_inc, remap_fd); + int r = osdmap.apply_incremental(pending_inc); + assert(r == 0); + modified = true; + } else { + cout << "no remaps proposed" << std::endl; + } + } + if (remap_file != "-") { + ::close(remap_fd); + } if (!import_crush.empty()) { bufferlist cbl; @@ -485,7 +596,8 @@ int main(int argc, const char **argv) if (!print && !tree && !modified && export_crush.empty() && import_crush.empty() && test_map_pg.empty() && test_map_object.empty() && - !test_map_pgs && !test_map_pgs_dump && !test_map_pgs_dump_all) { + !test_map_pgs && !test_map_pgs_dump && !test_map_pgs_dump_all && + !remap && !remap_cleanup) { cerr << me << ": no action specified?" << std::endl; usage(); } -- 2.39.5