]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/mon/OSDMonitor.cc
import ceph quincy 17.2.1
[ceph.git] / ceph / src / mon / OSDMonitor.cc
index 276efcd04dcabcf6860104c2c6e04e81172fdfdc..0d63ba8b5f6100c9263514e9b71aed440d33405a 100644 (file)
@@ -5253,6 +5253,16 @@ void OSDMonitor::tick()
       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;
@@ -6032,7 +6042,31 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
       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;
@@ -12676,10 +12710,14 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
             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,
@@ -12687,8 +12725,18 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
     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;
@@ -12696,11 +12744,31 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       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;
@@ -12714,16 +12782,27 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
           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);
@@ -12731,12 +12810,24 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
                                                  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,
@@ -14620,7 +14711,7 @@ void OSDMonitor::trigger_degraded_stretch_mode(const set<int>& dead_buckets,
       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();
@@ -14640,7 +14731,7 @@ void OSDMonitor::trigger_recovery_stretch_mode()
   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();
@@ -14726,7 +14817,7 @@ void OSDMonitor::trigger_healthy_stretch_mode()
       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();