do_propose = true;
}
}
+ for (auto p = osdmap.range_blocklist.begin();
+ p != osdmap.range_blocklist.end();
+ ++p) {
+ if (p->second < now) {
+ dout(10) << "expiring range_blocklist item " << p->first
+ << " expired " << p->second << " < now " << now << dendl;
+ pending_inc.old_range_blocklist.push_back(p->first);
+ do_propose = true;
+ }
+ }
if (try_prune_purged_snaps()) {
do_propose = true;
f->close_section();
f->flush(rdata);
}
- ss << "listed " << osdmap.blocklist.size() << " entries";
+ if (f)
+ f->open_array_section("range_blocklist");
+
+ for (auto p = osdmap.range_blocklist.begin();
+ p != osdmap.range_blocklist.end();
+ ++p) {
+ if (f) {
+ f->open_object_section("entry");
+ f->dump_string("range", p->first.get_legacy_str());
+ f->dump_stream("until") << p->second;
+ f->close_section();
+ } else {
+ stringstream ss;
+ string s;
+ ss << p->first << " " << p->second;
+ getline(ss, s);
+ s += "\n";
+ rdata.append(s);
+ }
+ }
+ if (f) {
+ f->close_section();
+ f->flush(rdata);
+ }
+ ss << "listed " << osdmap.blocklist.size() + osdmap.range_blocklist.size() << " entries";
} else if (prefix == "osd pool ls") {
string detail;
prefix == "osd blacklist clear") {
pending_inc.new_blocklist.clear();
std::list<std::pair<entity_addr_t,utime_t > > blocklist;
- osdmap.get_blocklist(&blocklist);
+ std::list<std::pair<entity_addr_t,utime_t > > range_b;
+ osdmap.get_blocklist(&blocklist, &range_b);
for (const auto &entry : blocklist) {
pending_inc.old_blocklist.push_back(entry.first);
}
+ for (const auto &entry : range_b) {
+ pending_inc.old_range_blocklist.push_back(entry.first);
+ }
ss << " removed all blocklist entries";
getline(ss, rs);
wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
return true;
} else if (prefix == "osd blocklist" ||
prefix == "osd blacklist") {
- string addrstr;
+ string addrstr, rangestr;
+ bool range = false;
cmd_getval(cmdmap, "addr", addrstr);
+ if (cmd_getval(cmdmap, "range", rangestr)) {
+ if (rangestr == "range") {
+ range = true;
+ } else {
+ ss << "Did you mean to specify \"osd blocklist range\"?";
+ err = -EINVAL;
+ goto reply;
+ }
+ }
entity_addr_t addr;
if (!addr.parse(addrstr)) {
ss << "unable to parse address " << addrstr;
goto reply;
}
else {
- if (osdmap.require_osd_release >= ceph_release_t::nautilus) {
- // always blocklist type ANY
- addr.set_type(entity_addr_t::TYPE_ANY);
+ if (range) {
+ if (!addr.maybe_cidr()) {
+ ss << "You specified a range command, but " << addr
+ << " does not parse as a CIDR range";
+ err = -EINVAL;
+ goto reply;
+ }
+ addr.type = entity_addr_t::TYPE_CIDR;
+ err = check_cluster_features(CEPH_FEATUREMASK_RANGE_BLOCKLIST, ss);
+ if (err) {
+ goto reply;
+ }
+ if ((addr.is_ipv4() && addr.get_nonce() > 32) ||
+ (addr.is_ipv6() && addr.get_nonce() > 128)) {
+ ss << "Too many bits in range for that protocol!";
+ err = -EINVAL;
+ goto reply;
+ }
} else {
- addr.set_type(entity_addr_t::TYPE_LEGACY);
+ if (osdmap.require_osd_release >= ceph_release_t::nautilus) {
+ // always blocklist type ANY
+ addr.set_type(entity_addr_t::TYPE_ANY);
+ } else {
+ addr.set_type(entity_addr_t::TYPE_LEGACY);
+ }
}
string blocklistop;
g_conf()->mon_osd_blocklist_default_expire);
expires += d;
- pending_inc.new_blocklist[addr] = expires;
+ auto add_to_pending_blocklists = [](auto& nb, auto& ob,
+ const auto& addr,
+ const auto& expires) {
+ nb[addr] = expires;
+ // cancel any pending un-blocklisting request too
+ auto it = std::find(ob.begin(),
+ ob.end(), addr);
+ if (it != ob.end()) {
+ ob.erase(it);
+ }
+ };
+ if (range) {
+ add_to_pending_blocklists(pending_inc.new_range_blocklist,
+ pending_inc.old_range_blocklist,
+ addr, expires);
- {
- // cancel any pending un-blocklisting request too
- auto it = std::find(pending_inc.old_blocklist.begin(),
- pending_inc.old_blocklist.end(), addr);
- if (it != pending_inc.old_blocklist.end()) {
- pending_inc.old_blocklist.erase(it);
- }
- }
+ } else {
+ add_to_pending_blocklists(pending_inc.new_blocklist,
+ pending_inc.old_blocklist,
+ addr, expires);
+ }
ss << "blocklisting " << addr << " until " << expires << " (" << d << " sec)";
getline(ss, rs);
get_last_committed() + 1));
return true;
} else if (blocklistop == "rm") {
- if (osdmap.is_blocklisted(addr) ||
- pending_inc.new_blocklist.count(addr)) {
- if (osdmap.is_blocklisted(addr))
- pending_inc.old_blocklist.push_back(addr);
- else
- pending_inc.new_blocklist.erase(addr);
+ auto rm_from_pending_blocklists = [](const auto& addr,
+ auto& blocklist,
+ auto& ob, auto& pb) {
+ if (blocklist.count(addr)) {
+ ob.push_back(addr);
+ return true;
+ } else if (pb.count(addr)) {
+ pb.erase(addr);
+ return true;
+ }
+ return false;
+ };
+ if ((!range && rm_from_pending_blocklists(addr, osdmap.blocklist,
+ pending_inc.old_blocklist,
+ pending_inc.new_blocklist)) ||
+ (range && rm_from_pending_blocklists(addr, osdmap.range_blocklist,
+ pending_inc.old_range_blocklist,
+ pending_inc.new_range_blocklist))) {
ss << "un-blocklisting " << addr;
getline(ss, rs);
wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
newp.peering_crush_bucket_count = new_site_count;
newp.peering_crush_mandatory_member = remaining_site;
newp.min_size = pgi.second.min_size / 2; // only support 2 zones now
- newp.last_force_op_resend = pending_inc.epoch;
+ newp.set_last_force_op_resend(pending_inc.epoch);
}
}
propose_pending();
for (auto pgi : osdmap.pools) {
if (pgi.second.peering_crush_bucket_count) {
pg_pool_t& newp = *pending_inc.get_new_pool(pgi.first, &pgi.second);
- newp.last_force_op_resend = pending_inc.epoch;
+ newp.set_last_force_op_resend(pending_inc.epoch);
}
}
propose_pending();
newp.peering_crush_bucket_count = osdmap.stretch_bucket_count;
newp.peering_crush_mandatory_member = CRUSH_ITEM_NONE;
newp.min_size = g_conf().get_val<uint64_t>("mon_stretch_pool_min_size");
- newp.last_force_op_resend = pending_inc.epoch;
+ newp.set_last_force_op_resend(pending_inc.epoch);
}
}
propose_pending();