summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-10-14 16:56:41 -0700
committerSage Weil <sage@inktank.com>2013-10-14 16:56:41 -0700
commit7a3e13de0d9997820325576128d3f82e08de24fc (patch)
tree1e69ea01f525cab852d295b99b42e2682b5bf44d
parentb0994e7011b3427bcd685e3d89e4eb61d0c25a7e (diff)
parentdd33c9802f3438391c57e18854debd9d4203f002 (diff)
downloadceph-7a3e13de0d9997820325576128d3f82e08de24fc.tar.gz
Merge pull request #712 from ceph/wip-mon-pool-set
rework ceph osd pool set <pool> <field> <val> Reviewed-by: Sage Weil <sage@inktank.com>
-rwxr-xr-xqa/workunits/cephtool/test.sh3
-rw-r--r--src/mon/MonCommands.h4
-rw-r--r--src/mon/OSDMonitor.cc193
-rw-r--r--src/mon/OSDMonitor.h3
-rw-r--r--src/osd/osd_types.cc3
-rw-r--r--src/osd/osd_types.h22
6 files changed, 158 insertions, 70 deletions
diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh
index 09e55b9a842..b098b13ad71 100755
--- a/qa/workunits/cephtool/test.sh
+++ b/qa/workunits/cephtool/test.sh
@@ -325,6 +325,9 @@ ceph osd pool set data size 3
ceph osd pool get data size | grep 'size: 3'
ceph osd pool set data size 2
+ceph osd pool set data hashpspool true
+ceph osd pool set data hashpspool false
+
ceph osd pool get rbd crush_ruleset | grep 'crush_ruleset: 2'
ceph osd thrash 10
diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h
index 33e00a98d30..d9fc56e032d 100644
--- a/src/mon/MonCommands.h
+++ b/src/mon/MonCommands.h
@@ -507,8 +507,8 @@ COMMAND("osd pool get " \
"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 " \
- "name=val,type=CephInt", \
+ "name=var,type=CephChoices,strings=size|min_size|crash_replay_interval|pg_num|pgp_num|crush_ruleset|hashpspool " \
+ "name=val,type=CephString", \
"set pool parameter <var> to <val>", "osd", "rw", "cli,rest")
// 'val' is a CephString because it can include a unit. Perhaps
// there should be a Python type for validation/conversion of strings
diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc
index 9144736d801..425375b29e2 100644
--- a/src/mon/OSDMonitor.cc
+++ b/src/mon/OSDMonitor.cc
@@ -2618,6 +2618,125 @@ void OSDMonitor::parse_loc_map(const vector<string>& args, map<string,string> *
}
}
+int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
+ stringstream& ss)
+{
+ string poolstr;
+ cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
+ int64_t pool = osdmap.lookup_pg_pool_name(poolstr.c_str());
+ if (pool < 0) {
+ ss << "unrecognized pool '" << poolstr << "'";
+ return -ENOENT;
+ }
+ string var;
+ cmd_getval(g_ceph_context, cmdmap, "var", var);
+
+ pg_pool_t p = *osdmap.get_pg_pool(pool);
+ if (pending_inc.new_pools.count(pool))
+ p = pending_inc.new_pools[pool];
+
+ // accept val as a json string or int, and parse out int or float
+ // values from the string as needed
+ string val;
+ cmd_getval(g_ceph_context, cmdmap, "val", val);
+ string interr;
+ int64_t n = 0;
+ if (!cmd_getval(g_ceph_context, cmdmap, "val", n))
+ n = strict_strtoll(val.c_str(), 10, &interr);
+ string floaterr;
+ float f;
+ if (!cmd_getval(g_ceph_context, cmdmap, "val", f))
+ f = strict_strtod(val.c_str(), &floaterr);
+
+ if (var == "size") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ if (n == 0 || n > 10) {
+ ss << "pool size must be between 1 and 10";
+ return -EINVAL;
+ }
+ p.size = n;
+ if (n < p.min_size)
+ p.min_size = n;
+ ss << "set pool " << pool << " size to " << n;
+ } else if (var == "min_size") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ p.min_size = n;
+ ss << "set pool " << pool << " min_size to " << n;
+ } else if (var == "crash_replay_interval") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ p.crash_replay_interval = n;
+ ss << "set pool " << pool << " to crash_replay_interval to " << n;
+ } else if (var == "pg_num") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ if (n <= (int)p.get_pg_num()) {
+ ss << "specified pg_num " << n << " <= current " << p.get_pg_num();
+ } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) {
+ ss << "currently creating pgs, wait";
+ return -EAGAIN;
+ } else {
+ p.set_pg_num(n);
+ ss << "set pool " << pool << " pg_num to " << n;
+ }
+ } else if (var == "pgp_num") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ if (n > (int)p.get_pg_num()) {
+ ss << "specified pgp_num " << n << " > pg_num " << p.get_pg_num();
+ } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) {
+ ss << "still creating pgs, wait";
+ return -EAGAIN;
+ } else {
+ p.set_pgp_num(n);
+ ss << "set pool " << pool << " pgp_num to " << n;
+ }
+ } else if (var == "crush_ruleset") {
+ if (interr.length()) {
+ ss << "error parsing integer value '" << val << "': " << interr;
+ return -EINVAL;
+ }
+ if (osdmap.crush->rule_exists(n)) {
+ p.crush_ruleset = n;
+ ss << "set pool " << pool << " crush_ruleset to " << n;
+ } else {
+ ss << "crush ruleset " << n << " does not exist";
+ return -ENOENT;
+ }
+ } else if (var == "hashpspool") {
+ if (val == "true") {
+ p.flags |= pg_pool_t::FLAG_HASHPSPOOL;
+ ss << "set";
+ } else if (val == "false") {
+ p.flags ^= pg_pool_t::FLAG_HASHPSPOOL;
+ ss << "unset";
+ } else {
+ ss << "expecting value true or false";
+ return -EINVAL;
+ }
+ ss << " pool " << pool << " flag hashpspool";
+ } else {
+ ss << "unrecognized variable '" << var << "'";
+ return -EINVAL;
+ }
+
+ p.last_change = pending_inc.epoch;
+ pending_inc.new_pools[pool] = p;
+ return 0;
+}
+
bool OSDMonitor::prepare_command(MMonCommand *m)
{
bool ret = false;
@@ -3586,73 +3705,13 @@ done:
return true;
}
} else if (prefix == "osd pool set") {
- // set a pool variable to a positive int
- string poolstr;
- cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
- int64_t pool = osdmap.lookup_pg_pool_name(poolstr.c_str());
- if (pool < 0) {
- ss << "unrecognized pool '" << poolstr << "'";
- err = -ENOENT;
- } else {
- const pg_pool_t *p = osdmap.get_pg_pool(pool);
- int64_t n;
- cmd_getval(g_ceph_context, cmdmap, "val", n);
- string var;
- cmd_getval(g_ceph_context, cmdmap, "var", var);
- if (var == "size") {
- if (n == 0 || n > 10) {
- ss << "pool size must be between 1 and 10";
- err = -EINVAL;
- goto reply;
- }
- pending_inc.get_new_pool(pool, p)->size = n;
- if (n < p->min_size)
- pending_inc.get_new_pool(pool, p)->min_size = n;
- ss << "set pool " << pool << " size to " << n;
- } else if (var == "min_size") {
- pending_inc.get_new_pool(pool, p)->min_size = n;
- ss << "set pool " << pool << " min_size to " << n;
- } else if (var == "crash_replay_interval") {
- pending_inc.get_new_pool(pool, p)->crash_replay_interval = n;
- ss << "set pool " << pool << " to crash_replay_interval to " << n;
- } else if (var == "pg_num") {
- if (n <= p->get_pg_num()) {
- ss << "specified pg_num " << n << " <= current " << p->get_pg_num();
- err = -EINVAL;
- } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) {
- ss << "busy creating pgs; try again later";
- err = -EAGAIN;
- } else {
- pending_inc.get_new_pool(pool, p)->set_pg_num(n);
- ss << "set pool " << pool << " pg_num to " << n;
- }
- } else if (var == "pgp_num") {
- if (n > p->get_pg_num()) {
- ss << "specified pgp_num " << n << " > pg_num " << p->get_pg_num();
- } else if (!mon->pgmon()->pg_map.creating_pgs.empty()) {
- ss << "busy creating pgs; try again later";
- err = -EAGAIN;
- } else {
- pending_inc.get_new_pool(pool, p)->set_pgp_num(n);
- ss << "set pool " << pool << " pgp_num to " << n;
- }
- } else if (var == "crush_ruleset") {
- if (osdmap.crush->rule_exists(n)) {
- pending_inc.get_new_pool(pool, p)->crush_ruleset = n;
- ss << "set pool " << pool << " crush_ruleset to " << n;
- } else {
- ss << "crush ruleset " << n << " does not exist";
- err = -ENOENT;
- }
- } else {
- err = -EINVAL;
- goto reply;
- }
- pending_inc.get_new_pool(pool, p)->last_change = pending_inc.epoch;
- getline(ss, rs);
- wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs, get_last_committed()));
- return true;
- }
+ err = prepare_command_pool_set(cmdmap, ss);
+ if (err < 0)
+ goto reply;
+
+ getline(ss, rs);
+ wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, rs, get_last_committed()));
+ return true;
} else if (prefix == "osd tier add") {
string poolstr;
cmd_getval(g_ceph_context, cmdmap, "pool", poolstr);
diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h
index 304f9c4f609..439c8435055 100644
--- a/src/mon/OSDMonitor.h
+++ b/src/mon/OSDMonitor.h
@@ -324,6 +324,9 @@ private:
bool preprocess_command(MMonCommand *m);
bool prepare_command(MMonCommand *m);
+ int prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
+ stringstream& ss);
+
void handle_osd_timeouts(const utime_t &now,
std::map<int,utime_t> &last_osd_report);
void mark_all_down();
diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc
index 27f7b171677..1a9dde665cf 100644
--- a/src/osd/osd_types.cc
+++ b/src/osd/osd_types.cc
@@ -655,6 +655,7 @@ void pool_snap_info_t::generate_test_instances(list<pool_snap_info_t*>& o)
void pg_pool_t::dump(Formatter *f) const
{
f->dump_unsigned("flags", get_flags());
+ f->dump_string("flags_names", get_flags_string());
f->dump_int("type", get_type());
f->dump_int("size", get_size());
f->dump_int("min_size", get_min_size());
@@ -1054,7 +1055,7 @@ ostream& operator<<(ostream& out, const pg_pool_t& p)
<< " last_change " << p.get_last_change()
<< " owner " << p.get_auid();
if (p.flags)
- out << " flags " << p.flags;
+ out << " flags " << p.get_flags_string();
if (p.crash_replay_interval)
out << " crash_replay_interval " << p.crash_replay_interval;
if (p.quota_max_bytes)
diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h
index a54fc65f375..8ceeb539c1a 100644
--- a/src/osd/osd_types.h
+++ b/src/osd/osd_types.h
@@ -725,6 +725,28 @@ struct pg_pool_t {
FLAG_FULL = 2, // pool is full
};
+ static const char *get_flag_name(int f) {
+ switch (f) {
+ case FLAG_HASHPSPOOL: return "hashpspool";
+ case FLAG_FULL: return "full";
+ default: return "???";
+ }
+ }
+ static string get_flags_string(uint64_t f) {
+ string s;
+ for (unsigned n=0; f && n<64; ++n) {
+ if (f & (1ull << n)) {
+ if (s.length())
+ s += ",";
+ s += get_flag_name(1ull << n);
+ }
+ }
+ return s;
+ }
+ string get_flags_string() const {
+ return get_flags_string(flags);
+ }
+
typedef enum {
CACHEMODE_NONE = 0, ///< no caching
CACHEMODE_WRITEBACK = 1, ///< write to cache, flush later