"name=pools,type=CephPoolname,n=N,req=false", \
"dry run of reweight OSDs by PG distribution [overload-percentage-for-consideration, default 120]", \
"osd", "rw", "cli,rest")
-COMMAND("osd thrash " \
- "name=num_epochs,type=CephInt,range=0", \
- "thrash OSDs for <num_epochs>", "osd", "rw", "cli,rest")
COMMAND("osd df " \
"name=output_method,type=CephChoices,strings=plain|tree,req=false", \
"show OSD utilization", "osd", "r", "cli,rest")
cct(cct),
inc_osd_cache(g_conf->mon_osd_cache_size),
full_osd_cache(g_conf->mon_osd_cache_size),
- thrash_map(0), thrash_last_up_osd(-1),
op_tracker(cct, true, 1)
{}
}
}
-bool OSDMonitor::thrash()
-{
- if (!thrash_map)
- return false;
-
- thrash_map--;
- int o;
-
- int osd_num = osdmap.get_num_osds();
- if (osd_num == 0)
- return false;
-
- // mark a random osd up_thru..
- if (rand() % 4 == 0 || thrash_last_up_osd < 0)
- o = rand() % osd_num;
- else
- o = thrash_last_up_osd;
- if (osdmap.is_up(o)) {
- dout(5) << "thrash_map osd." << o << " up_thru" << dendl;
- pending_inc.new_up_thru[o] = osdmap.get_epoch();
- }
-
- // mark a random osd up/down
- o = rand() % osd_num;
- if (osdmap.is_up(o)) {
- dout(5) << "thrash_map osd." << o << " down" << dendl;
- pending_inc.new_state[o] = CEPH_OSD_UP;
- } else if (osdmap.exists(o)) {
- dout(5) << "thrash_map osd." << o << " up" << dendl;
- pending_inc.new_state[o] = CEPH_OSD_UP;
- pending_inc.new_up_client[o] = entity_addr_t();
- pending_inc.new_up_cluster[o] = entity_addr_t();
- pending_inc.new_hb_back_up[o] = entity_addr_t();
- pending_inc.new_weight[o] = CEPH_OSD_IN;
- thrash_last_up_osd = o;
- }
-
- // mark a random osd in
- o = rand() % osd_num;
- if (osdmap.exists(o)) {
- dout(5) << "thrash_map osd." << o << " in" << dendl;
- pending_inc.new_weight[o] = CEPH_OSD_IN;
- }
-
- // mark a random osd out
- o = rand() % osd_num;
- if (osdmap.exists(o)) {
- dout(5) << "thrash_map osd." << o << " out" << dendl;
- pending_inc.new_weight[o] = CEPH_OSD_OUT;
- }
-
- // generate some pg_temp entries.
- // let's assume the ceph::unordered_map iterates in a random-ish order.
- int pg_num = mon->pgmon()->pg_map.pg_stat.size();
- if (pg_num == 0)
- return true;
- int n = rand() % pg_num;
- ceph::unordered_map<pg_t,pg_stat_t>::iterator p = mon->pgmon()->pg_map.pg_stat.begin();
- ceph::unordered_map<pg_t,pg_stat_t>::iterator e = mon->pgmon()->pg_map.pg_stat.end();
- while (n--)
- ++p;
-
- for (int i = std::min(pg_num, 50); i > 0; i--) {
- unsigned size = osdmap.get_pg_size(p->first);
- vector<int> v;
- bool have_real_osd = false;
- for (int j=0; j < (int)size; j++) {
- o = rand() % osd_num;
- if (osdmap.exists(o) && std::find(v.begin(), v.end(), o) == v.end()) {
- have_real_osd = true;
- v.push_back(o);
- }
- }
- for (vector<int>::iterator q = p->second.acting.begin();
- q != p->second.acting.end() && v.size() < size;
- ++q) {
- if (std::find(v.begin(), v.end(), *q) == v.end()) {
- if (*q != CRUSH_ITEM_NONE)
- have_real_osd = true;
- v.push_back(*q);
- }
- }
- if (osdmap.pg_is_ec(p->first)) {
- while (v.size() < size)
- v.push_back(CRUSH_ITEM_NONE);
- }
- if (!v.empty() && have_real_osd)
- pending_inc.new_pg_temp[p->first] = v;
- dout(5) << "thrash_map pg " << p->first << " pg_temp remapped to " << v << dendl;
-
- ++p;
- if (p == e)
- p = mon->pgmon()->pg_map.pg_stat.begin();
- }
- return true;
-}
-
void OSDMonitor::on_active()
{
update_logger();
- if (thrash_map) {
- if (mon->is_leader()) {
- if (thrash())
- propose_pending();
- } else {
- thrash_map = 0;
- }
- }
-
if (mon->is_leader())
mon->clog->info() << "osdmap " << osdmap << "\n";
new Monitor::C_Command(mon, op, 0, rs, rdata, get_last_committed() + 1));
return true;
}
- } else if (prefix == "osd thrash") {
- int64_t num_epochs;
- cmd_getval(g_ceph_context, cmdmap, "num_epochs", num_epochs, int64_t(0));
- // thrash_map is a member var
- thrash_map = num_epochs;
- ss << "will thrash map for " << thrash_map << " epochs";
- ret = thrash();
- err = 0;
- if (ret)
- goto update;
} else {
err = -EINVAL;
}