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
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
}
+/**
+ * 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.
*
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;
}
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;
}