rdata.append(ss.str());
ss.str("");
goto reply;
+ } else if (prefix == "osd pool application enable" ||
+ prefix == "osd pool application disable" ||
+ prefix == "osd pool application set" ||
+ prefix == "osd pool application rm") {
+ bool changed = false;
+ r = preprocess_command_pool_application(prefix, cmdmap, ss, &changed);
+ if (r != 0) {
+ // Error, reply.
+ goto reply;
+ } else if (changed) {
+ // Valid mutation, proceed to prepare phase
+ return false;
+ } else {
+ // Idempotent case, reply
+ goto reply;
+ }
} else {
// try prepare update
return false;
int OSDMonitor::prepare_command_pool_application(const string &prefix,
const cmdmap_t& cmdmap,
stringstream& ss)
+{
+ return _command_pool_application(prefix, cmdmap, ss, nullptr, true);
+}
+
+int OSDMonitor::preprocess_command_pool_application(const string &prefix,
+ const cmdmap_t& cmdmap,
+ stringstream& ss,
+ bool *modified)
+{
+ return _command_pool_application(prefix, cmdmap, ss, modified, false);
+}
+
+
+/**
+ * Common logic for preprocess and prepare phases of pool application
+ * tag commands. In preprocess mode we're only detecting invalid
+ * commands, and determining whether it was a modification or a no-op.
+ * In prepare mode we're actually updating the pending state.
+ */
+int OSDMonitor::_command_pool_application(const string &prefix,
+ const cmdmap_t& cmdmap,
+ stringstream& ss,
+ bool *modified,
+ bool preparing)
{
string pool_name;
cmd_getval(cct, cmdmap, "pool", pool_name);
}
pg_pool_t p = *osdmap.get_pg_pool(pool);
- if (pending_inc.new_pools.count(pool)) {
- p = pending_inc.new_pools[pool];
+ if (preparing) {
+ if (pending_inc.new_pools.count(pool)) {
+ p = pending_inc.new_pools[pool];
+ }
}
string app;
ceph_abort();
}
- p.last_change = pending_inc.epoch;
- pending_inc.new_pools[pool] = p;
+ if (preparing) {
+ p.last_change = pending_inc.epoch;
+ pending_inc.new_pools[pool] = p;
+ }
+
+ // Because we fell through this far, we didn't hit no-op cases,
+ // so pool was definitely modified
+ if (modified != nullptr) {
+ *modified = true;
+ }
+
return 0;
}
prefix == "osd pool application set" ||
prefix == "osd pool application rm") {
err = prepare_command_pool_application(prefix, cmdmap, ss);
- if (err == -EAGAIN)
+ if (err == -EAGAIN) {
goto wait;
- if (err < 0)
+ } else if (err < 0) {
goto reply;
-
- getline(ss, rs);
- wait_for_finished_proposal(
- op, new Monitor::C_Command(mon, op, 0, rs, get_last_committed() + 1));
- return true;
+ } else {
+ goto update;
+ }
} else if (prefix == "osd force-create-pg") {
pg_t pgid;
string pgidstr;
int prepare_command_pool_set(const cmdmap_t& cmdmap,
stringstream& ss);
+
int prepare_command_pool_application(const string &prefix,
const cmdmap_t& cmdmap,
stringstream& ss);
+ int preprocess_command_pool_application(const string &prefix,
+ const cmdmap_t& cmdmap,
+ stringstream& ss,
+ bool *modified);
+ int _command_pool_application(const string &prefix,
+ const cmdmap_t& cmdmap,
+ stringstream& ss,
+ bool *modified,
+ bool preparing);
bool handle_osd_timeouts(const utime_t &now,
std::map<int,utime_t> &last_osd_report);