]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: improve crush map validation 17805/head
authorSage Weil <sage@redhat.com>
Wed, 6 Sep 2017 02:46:48 +0000 (22:46 -0400)
committerKefu Chai <kchai@redhat.com>
Sat, 21 Oct 2017 16:24:05 +0000 (00:24 +0800)
- move into OSDMap method
- ensure that rules exist for each pool
- ensure pool type matches rule type
- ensure rule mask min/max size cover the pool size

Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 8f8f0b25058ff7319ec9d023f0eceb5832d0ecff)

src/mon/OSDMonitor.cc
src/osd/OSDMap.cc
src/osd/OSDMap.h

index 831dd0cb2ede0df0073273b76fa4fdfea589a5f7..d92443c159ffd6cf811878350a10a0b78d03b469 100644 (file)
@@ -7655,16 +7655,9 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       goto reply;
     }
 
-    const auto& osdmap_pools = osdmap.get_pools();
-    for (auto pit = osdmap_pools.begin(); pit != osdmap_pools.end(); ++pit) {
-      const int64_t pool_id = pit->first;
-      const pg_pool_t &pool = pit->second;
-      int ruleno = pool.get_crush_rule();
-      if (!crush.rule_exists(ruleno)) {
-       ss << " the crush rule no "<< ruleno << " for pool id " << pool_id << " is in use";
-       err = -EINVAL;
-       goto reply;
-      }
+    err = osdmap.validate_crush_rules(&crush, &ss);
+    if (err < 0) {
+      goto reply;
     }
 
     if (g_conf->mon_osd_crush_smoke_test) {
index e8b1d56676692d03747959db6f450372d47ca031..4d98b2e0726166c7be2356b0d13598262d97563a 100644 (file)
@@ -3293,6 +3293,37 @@ bool OSDMap::crush_rule_in_use(int rule_id) const
   return false;
 }
 
+int OSDMap::validate_crush_rules(CrushWrapper *newcrush,
+                                ostream *ss) const
+{
+  for (auto& i : pools) {
+    auto& pool = i.second;
+    int ruleno = pool.get_crush_rule();
+    if (!newcrush->rule_exists(ruleno)) {
+      *ss << "pool " << i.first << " references crush_rule " << ruleno
+         << " but it is not present";
+      return -EINVAL;
+    }
+    if (newcrush->get_rule_mask_ruleset(ruleno) != ruleno) {
+      *ss << "rule " << ruleno << " mask ruleset does not match rule id";
+      return -EINVAL;
+    }
+    if (newcrush->get_rule_mask_type(ruleno) != (int)pool.get_type()) {
+      *ss << "pool " << i.first << " type does not match rule " << ruleno;
+      return -EINVAL;
+    }
+    if (pool.get_size() < (int)newcrush->get_rule_mask_min_size(ruleno) ||
+       pool.get_size() > (int)newcrush->get_rule_mask_max_size(ruleno)) {
+      *ss << "pool " << i.first << " size " << pool.get_size() << " does not"
+         << " fall within rule " << ruleno
+         << " min_size " << newcrush->get_rule_mask_min_size(ruleno)
+         << " and max_size " << newcrush->get_rule_mask_max_size(ruleno);
+      return -EINVAL;
+    }
+  }
+  return 0;
+}
+
 int OSDMap::build_simple_optioned(CephContext *cct, epoch_t e, uuid_d &fsid,
                                  int nosd, int pg_bits, int pgp_bits,
                                  bool default_pool)
index 65348d5d3a67bf30826cd142a0f1c1ac2290c8ce..6ba56511823d1390ad4aa5a4bfcd7b8cfcaabe40 100644 (file)
@@ -1344,6 +1344,8 @@ public:
 
   bool crush_rule_in_use(int rule_id) const;
 
+  int validate_crush_rules(CrushWrapper *crush, ostream *ss) const;
+
   void clear_temp() {
     pg_temp->clear();
     primary_temp->clear();