]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: prevent cache pools being used CephFS
authorJohn Spray <john.spray@redhat.com>
Mon, 15 Sep 2014 19:47:18 +0000 (20:47 +0100)
committerGreg Farnum <greg@inktank.com>
Wed, 17 Sep 2014 00:16:23 +0000 (17:16 -0700)
Fixes two things:
 * EC pools are now permissible if they have a cache overlay
 * Pools are not permissible if they are a cache tier.

Fixes: #9435
Signed-off-by: John Spray <john.spray@redhat.com>
qa/workunits/cephtool/test.sh
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h

index 97b2b3d3c4ebdeac826a1120d448415d8d94b003..fa2002316cb032d847342b3a2bcb1718589a1d33 100755 (executable)
@@ -414,7 +414,7 @@ function test_mon_mds()
   expect_false ceph mds set allow_new_snaps taco
 
   # we should never be able to add EC pools as data or metadata pools
-  # create an ec-pool
+  # create an ec-pool...
   ceph osd pool create mds-ec-pool 10 10 erasure
   set +e
   ceph mds add_data_pool mds-ec-pool 2>$TMPFILE
@@ -441,6 +441,39 @@ function test_mon_mds()
   ceph fs new cephfs mds-ec-pool mds-ec-pool 2>$TMPFILE
   check_response 'erasure-code' $? 22
   set -e
+
+  # ... however if we create a cache tier in front of the EC pool, we should
+  # be permitted to use it...
+  ceph osd pool create mds-tier 2
+  ceph osd tier add mds-ec-pool mds-tier
+  ceph osd tier set-overlay mds-ec-pool mds-tier
+  ceph osd tier cache-mode mds-tier writeback
+  tier_poolnum=$(ceph osd dump | grep "pool.* 'mds-tier" | awk '{print $2;}')
+
+  set -e
+  ceph fs new cephfs fs_metadata mds-ec-pool
+  ceph fs rm cephfs --yes-i-really-mean-it
+
+  # ... but we should be forbidden from using the cache pool in the FS directly.
+  set +e
+  ceph mds newfs $metadata_poolnum $tier_poolnum --yes-i-really-mean-it 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  ceph mds newfs $tier_poolnum $data_poolnum --yes-i-really-mean-it 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  ceph mds newfs $tier_poolnum $tier_poolnum --yes-i-really-mean-it 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  ceph fs new cephfs fs_metadata mds-tier 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  ceph fs new cephfs mds-tier fs_data 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  ceph fs new cephfs mds-tier mds-tier 2>$TMPFILE
+  check_response 'in use as a cache tier' $? 22
+  set -e
+
+  # Clean up tier + EC pools
+  ceph osd tier remove-overlay mds-ec-pool
+  ceph osd tier remove mds-ec-pool mds-tier
+  ceph osd pool delete mds-tier mds-tier --yes-i-really-really-mean-it
   ceph osd pool delete mds-ec-pool mds-ec-pool --yes-i-really-really-mean-it
 
   ceph mds stat
index 520eb6947c97e71c5e241266bbc04af282f49196..34216ea1d06038d9ff68ecbd41708fffc50c638f 100644 (file)
@@ -958,6 +958,45 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
 }
 
 
+/**
+ * Return 0 if the pool is suitable for use with CephFS, or
+ * in case of errors return a negative error code, and populate
+ * the passed stringstream with an explanation.
+ */
+int MDSMonitor::_check_pool(
+    const int64_t pool_id,
+    std::stringstream *ss) const
+{
+  assert(ss != NULL);
+
+  const pg_pool_t *pool = mon->osdmon()->osdmap.get_pg_pool(pool_id);
+  if (!pool) {
+    *ss << "pool id '" << pool_id << "' does not exist";
+    return -ENOENT;
+  }
+
+  const string& pool_name = mon->osdmon()->osdmap.get_pool_name(pool_id);
+
+  if (pool->is_erasure()) {
+    // EC pools are only acceptable with a cache tier overlay
+    if (!pool->has_tiers() || !pool->has_read_tier() || !pool->has_write_tier()) {
+      *ss << "pool '" << pool_name << "' (id '" << pool_id << "')"
+         << " is an erasure-code pool";
+      return -EINVAL;
+    }
+  }
+
+  if (pool->is_tier()) {
+    *ss << " pool '" << pool_name << "' (id '" << pool_id
+      << "') is already in use as a cache tier.";
+    return -EINVAL;
+  }
+
+  // Nothing special about this pool, so it is permissible
+  return 0;
+}
+
+
 /**
  * Handle a command for creating or removing a filesystem.
  *
@@ -990,30 +1029,13 @@ bool MDSMonitor::management_command(
       return true;
     }
  
-    // Check that the requested pools exist
-    const pg_pool_t *p = mon->osdmon()->osdmap.get_pg_pool(data);
-    if (!p) {
-      ss << "pool id '" << data << "' does not exist";
-      r = -ENOENT;
-      return true;
-    } else if (p->is_erasure()) {
-      const string& pn = mon->osdmon()->osdmap.get_pool_name(data);
-      ss << "pool '" << pn << "' (id '" << data << "')"
-         << " is an erasure-code pool";
-      r = -EINVAL;
+    r = _check_pool(data, &ss);
+    if (r) {
       return true;
     }
 
-    p = mon->osdmon()->osdmap.get_pg_pool(metadata);
-    if (!p) {
-      ss << "pool id '" << metadata << "' does not exist";
-      r = -ENOENT;
-      return true;
-    } else if (p->is_erasure()) {
-      const string& pn = mon->osdmon()->osdmap.get_pool_name(metadata);
-      ss << "pool '" << pn << "' (id '" << metadata << "')"
-         << " is an erasure-code pool";
-      r = -EINVAL;
+    r = _check_pool(metadata, &ss);
+    if (r) {
       return true;
     }
 
@@ -1100,15 +1122,13 @@ bool MDSMonitor::management_command(
       request_proposal(mon->osdmon());
     }
 
-    if (data_pool->is_erasure()) {
-      ss << "data pool '" << data_name << " is an erasure-code pool";
-      r = -EINVAL;
+    r = _check_pool(data, &ss);
+    if (r) {
       return true;
     }
 
-    if (metadata_pool->is_erasure()) {
-      ss << "metadata pool '" << metadata_name << " is an erasure-code pool";
-      r = -EINVAL;
+    r = _check_pool(metadata, &ss);
+    if (r) {
       return true;
     }
 
index 0343c3247f892f6bcf4091067000044e89579de3..305730fe605edcc9a2b0c3fc278d977782f2ec09 100644 (file)
@@ -139,6 +139,8 @@ private:
   // MDS daemon GID to latest health state from that GID
   std::map<uint64_t, MDSHealth> pending_daemon_health;
   std::set<uint64_t> pending_daemon_health_rm;
+
+  int _check_pool(const int64_t pool_id, std::stringstream *ss) const;
 };
 
 #endif