1
0
mirror of https://github.com/ceph/ceph synced 2024-12-23 20:03:56 +00:00

mon: prevent cache pools being used CephFS

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: 

Signed-off-by: John Spray <john.spray@redhat.com>
This commit is contained in:
John Spray 2014-09-15 20:47:18 +01:00 committed by Greg Farnum
parent fdbfece81c
commit 80441cda8c
3 changed files with 83 additions and 28 deletions
qa/workunits/cephtool
src/mon

View File

@ -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

View 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;
}

View 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