:Version: Version ``0.48`` Argonaut and above.
+``nodelete``
+
+:Description: Set/Unset NODELETE flag on a given pool.
+:Type: Integer
+:Valid Range: 1 sets flag, 0 unsets flag
+:Version: Version ``FIXME``
+
+
+``nopgchange``
+
+:Description: Set/Unset NOPGCHANGE flag on a given pool.
+:Type: Integer
+:Valid Range: 1 sets flag, 0 unsets flag
+:Version: Version ``FIXME``
+
+
+``nosizechange``
+
+:Description: Set/Unset NOSIZECHANGE flag on a given pool.
+:Type: Integer
+:Valid Range: 1 sets flag, 0 unsets flag
+:Version: Version ``FIXME``
+
+
``hit_set_type``
:Description: Enables hit set tracking for cache pools.
ceph --format=xml osd pool get $TEST_POOL_GETSET auid | grep $auid
ceph osd pool set $TEST_POOL_GETSET auid 0
- ceph osd pool set $TEST_POOL_GETSET hashpspool true
- ceph osd pool set $TEST_POOL_GETSET hashpspool false
- ceph osd pool set $TEST_POOL_GETSET hashpspool 0
- ceph osd pool set $TEST_POOL_GETSET hashpspool 1
- expect_false ceph osd pool set $TEST_POOL_GETSET hashpspool asdf
- expect_false ceph osd pool set $TEST_POOL_GETSET hashpspool 2
+ for flag in hashpspool nodelete nopgchange nosizechange; do
+ ceph osd pool set $TEST_POOL_GETSET $flag false
+ ceph osd pool set $TEST_POOL_GETSET $flag true
+ ceph osd pool set $TEST_POOL_GETSET $flag 1
+ ceph osd pool set $TEST_POOL_GETSET $flag 0
+ expect_false ceph osd pool set $TEST_POOL_GETSET $flag asdf
+ expect_false ceph osd pool set $TEST_POOL_GETSET $flag 2
+ done
+ ceph osd pool set $TEST_POOL_GETSET nopgchange 1
+ expect_false ceph osd pool set $TEST_POOL_GETSET pg_num 10
+ expect_false ceph osd pool set $TEST_POOL_GETSET pgp_num 10
+ ceph osd pool set $TEST_POOL_GETSET nopgchange 0
+ ceph osd pool set $TEST_POOL_GETSET pg_num 10
+ ceph osd pool set $TEST_POOL_GETSET pgp_num 10
+
+ ceph osd pool set $TEST_POOL_GETSET nosizechange 1
+ expect_false ceph osd pool set $TEST_POOL_GETSET size 2
+ expect_false ceph osd pool set $TEST_POOL_GETSET min_size 2
+ ceph osd pool set $TEST_POOL_GETSET nosizechange 0
+ ceph osd pool set $TEST_POOL_GETSET size 2
+ ceph osd pool set $TEST_POOL_GETSET min_size 2
+
+ ceph osd pool set $TEST_POOL_GETSET nodelete 1
+ expect_false ceph osd pool delete $TEST_POOL_GETSET $TEST_POOL_GETSET --yes-i-really-really-mean-it
+ ceph osd pool set $TEST_POOL_GETSET nodelete 0
ceph osd pool delete $TEST_POOL_GETSET $TEST_POOL_GETSET --yes-i-really-really-mean-it
ceph osd pool get rbd crush_ruleset | grep 'crush_ruleset: 0'
) // list of erasure code plugins
OPTION(osd_pool_default_flags, OPT_INT, 0) // default flags for new pools
OPTION(osd_pool_default_flag_hashpspool, OPT_BOOL, true) // use new pg hashing to prevent pool/pg overlap
+OPTION(osd_pool_default_flag_nodelete, OPT_BOOL, false) // pool can't be deleted
+OPTION(osd_pool_default_flag_nopgchange, OPT_BOOL, false) // pool's pg and pgp num can't be changed
+OPTION(osd_pool_default_flag_nosizechange, OPT_BOOL, false) // pool's size and min size can't be changed
OPTION(osd_pool_default_hit_set_bloom_fpp, OPT_FLOAT, .05)
OPTION(osd_pool_default_cache_target_dirty_ratio, OPT_FLOAT, .4)
OPTION(osd_pool_default_cache_target_full_ratio, OPT_FLOAT, .8)
"get pool parameter <var>", "osd", "r", "cli,rest")
COMMAND("osd pool set " \
"name=pool,type=CephPoolname " \
- "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote " \
+ "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool|nodelete|nopgchange|nosizechange|hit_set_type|hit_set_period|hit_set_count|hit_set_fpp|debug_fake_ec_pool|target_max_bytes|target_max_objects|cache_target_dirty_ratio|cache_target_full_ratio|cache_min_flush_age|cache_min_evict_age|auid|min_read_recency_for_promote " \
"name=val,type=CephString " \
"name=force,type=CephChoices,strings=--yes-i-really-mean-it,req=false", \
"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
pi->type = pool_type;
pi->flags = g_conf->osd_pool_default_flags;
if (g_conf->osd_pool_default_flag_hashpspool)
- pi->flags |= pg_pool_t::FLAG_HASHPSPOOL;
+ pi->set_flag(pg_pool_t::FLAG_HASHPSPOOL);
+ if (g_conf->osd_pool_default_flag_nodelete)
+ pi->set_flag(pg_pool_t::FLAG_NODELETE);
+ if (g_conf->osd_pool_default_flag_nopgchange)
+ pi->set_flag(pg_pool_t::FLAG_NOPGCHANGE);
+ if (g_conf->osd_pool_default_flag_nosizechange)
+ pi->set_flag(pg_pool_t::FLAG_NOSIZECHANGE);
pi->size = size;
pi->min_size = min_size;
}
if (var == "size") {
+ if (p.has_flag(pg_pool_t::FLAG_NOSIZECHANGE)) {
+ ss << "pool size change is disabled; you must unset nosizechange flag for the pool first";
+ return -EPERM;
+ }
if (p.type == pg_pool_t::TYPE_ERASURE) {
ss << "can not change the size of an erasure-coded pool";
return -ENOTSUP;
if (n < p.min_size)
p.min_size = n;
} else if (var == "min_size") {
+ if (p.has_flag(pg_pool_t::FLAG_NOSIZECHANGE)) {
+ ss << "pool min size change is disabled; you must unset nosizechange flag for the pool first";
+ return -EPERM;
+ }
if (interr.length()) {
ss << "error parsing integer value '" << val << "': " << interr;
return -EINVAL;
}
p.crash_replay_interval = n;
} else if (var == "pg_num") {
+ if (p.has_flag(pg_pool_t::FLAG_NOPGCHANGE)) {
+ ss << "pool pg_num change is disabled; you must unset nopgchange flag for the pool first";
+ return -EPERM;
+ }
if (interr.length()) {
ss << "error parsing integer value '" << val << "': " << interr;
return -EINVAL;
}
p.set_pg_num(n);
} else if (var == "pgp_num") {
+ if (p.has_flag(pg_pool_t::FLAG_NOPGCHANGE)) {
+ ss << "pool pgp_num change is disabled; you must unset nopgchange flag for the pool first";
+ return -EPERM;
+ }
if (interr.length()) {
ss << "error parsing integer value '" << val << "': " << interr;
return -EINVAL;
return -ENOENT;
}
p.crush_ruleset = n;
- } else if (var == "hashpspool") {
+ } else if (var == "hashpspool" || var == "nodelete" || var == "nopgchange" ||
+ var == "nosizechange") {
+ uint64_t flag = pg_pool_t::get_flag_by_name(var);
// make sure we only compare against 'n' if we didn't receive a string
if (val == "true" || (interr.empty() && n == 1)) {
- p.flags |= pg_pool_t::FLAG_HASHPSPOOL;
+ p.set_flag(flag);
} else if (val == "false" || (interr.empty() && n == 0)) {
- p.flags &= ~pg_pool_t::FLAG_HASHPSPOOL;
+ p.unset_flag(flag);
} else {
ss << "expecting value 'true', 'false', '0', or '1'";
return -EINVAL;
return -EPERM;
}
+ if (p->has_flag(pg_pool_t::FLAG_NODELETE)) {
+ *ss << "pool deletion is disabled; you must unset nodelete flag for the pool first";
+ return -EPERM;
+ }
+
*ss << "pool '" << poolstr << "' removed";
return 0;
}
pools[pool].type = pg_pool_t::TYPE_REPLICATED;
pools[pool].flags = cct->_conf->osd_pool_default_flags;
if (cct->_conf->osd_pool_default_flag_hashpspool)
- pools[pool].flags |= pg_pool_t::FLAG_HASHPSPOOL;
+ pools[pool].set_flag(pg_pool_t::FLAG_HASHPSPOOL);
+ if (cct->_conf->osd_pool_default_flag_nodelete)
+ pools[pool].set_flag(pg_pool_t::FLAG_NODELETE);
+ if (cct->_conf->osd_pool_default_flag_nopgchange)
+ pools[pool].set_flag(pg_pool_t::FLAG_NOPGCHANGE);
+ if (cct->_conf->osd_pool_default_flag_nosizechange)
+ pools[pool].set_flag(pg_pool_t::FLAG_NOSIZECHANGE);
pools[pool].size = cct->_conf->osd_pool_default_size;
pools[pool].min_size = cct->_conf->get_osd_pool_default_min_size();
pools[pool].crush_ruleset = default_replicated_ruleset;
FLAG_FULL = 1<<1, // pool is full
FLAG_DEBUG_FAKE_EC_POOL = 1<<2, // require ReplicatedPG to act like an EC pg
FLAG_INCOMPLETE_CLONES = 1<<3, // may have incomplete clones (bc we are/were an overlay)
+ FLAG_NODELETE = 1<<4, // pool can't be deleted
+ FLAG_NOPGCHANGE = 1<<5, // pool's pg and pgp num can't be changed
+ FLAG_NOSIZECHANGE = 1<<6, // pool's size and min size can't be changed
};
static const char *get_flag_name(int f) {
case FLAG_FULL: return "full";
case FLAG_DEBUG_FAKE_EC_POOL: return "require_local_rollback";
case FLAG_INCOMPLETE_CLONES: return "incomplete_clones";
+ case FLAG_NODELETE: return "nodelete";
+ case FLAG_NOPGCHANGE: return "nopgchange";
+ case FLAG_NOSIZECHANGE: return "nosizechange";
default: return "???";
}
}
string get_flags_string() const {
return get_flags_string(flags);
}
+ static uint64_t get_flag_by_name(const string& name) {
+ if (name == "hashpspool")
+ return FLAG_HASHPSPOOL;
+ if (name == "full")
+ return FLAG_FULL;
+ if (name == "require_local_rollback")
+ return FLAG_DEBUG_FAKE_EC_POOL;
+ if (name == "incomplete_clones")
+ return FLAG_INCOMPLETE_CLONES;
+ if (name == "nodelete")
+ return FLAG_NODELETE;
+ if (name == "nopgchange")
+ return FLAG_NOPGCHANGE;
+ if (name == "nosizechange")
+ return FLAG_NOSIZECHANGE;
+ return 0;
+ }
typedef enum {
CACHEMODE_NONE = 0, ///< no caching
uint64_t get_flags() const { return flags; }
bool has_flag(uint64_t f) const { return flags & f; }
+ void set_flag(uint64_t f) { flags |= f; }
+ void unset_flag(uint64_t f) { flags &= ~f; }
/// This method will later return true for ec pools as well
bool ec_pool() const {
TEST_POOL=rbd
function TEST_osd_pool_get_set() {
- local dir=$1
- ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
- ./ceph osd pool set $TEST_POOL hashpspool 0 || return 1
- ! ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
- ./ceph osd pool set $TEST_POOL hashpspool 1 || return 1
- ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
- ./ceph osd pool set $TEST_POOL hashpspool false || return 1
- ! ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
- ./ceph osd pool set $TEST_POOL hashpspool false || return 1
- # check that setting false twice does not toggle to true (bug)
- ! ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
- ./ceph osd pool set $TEST_POOL hashpspool true || return 1
- ./ceph osd dump | grep 'pool 0' | grep hashpspool || return 1
+ local dir=$1 flag
+ for flag in hashpspool nodelete nopgchange nosizechange; do
+ if [ $flag = hashpspool ]; then
+ ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ else
+ ! ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ fi
+ ./ceph osd pool set $TEST_POOL $flag 0 || return 1
+ ! ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ ./ceph osd pool set $TEST_POOL $flag 1 || return 1
+ ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ ./ceph osd pool set $TEST_POOL $flag false || return 1
+ ! ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ ./ceph osd pool set $TEST_POOL $flag false || return 1
+ # check that setting false twice does not toggle to true (bug)
+ ! ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ ./ceph osd pool set $TEST_POOL $flag true || return 1
+ ./ceph osd dump | grep 'pool 0' | grep $flag || return 1
+ # cleanup
+ ./ceph osd pool set $TEST_POOL $flag 0 || return 1
+ done
local size=$(./ceph osd pool get $TEST_POOL size|awk '{print $2}')
local min_size=$(./ceph osd pool get $TEST_POOL min_size|awk '{print $2}')