default:
ceph_abort();
- return true;
+ return false;
}
}
} catch (const bad_cmd_get& e) {
bufferlist bl;
mon.reply_command(op, -EINVAL, e.what(), bl, get_last_committed());
- return true;
+ return false; /* nothing to propose */
}
case CEPH_MSG_POOLOP:
<< " race with concurrent pg_num[_pending] update, will retry"
<< dendl;
wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ return false; /* nothing to propose, yet */
}
if (m->ready) {
send_latest(op, beacon->version+1);
}
dout(1) << " ignoring beacon from non-active osd." << from << dendl;
- return false;
+ return false; /* nothing to propose */
}
last_osd_report[from].first = ceph_clock_now();
beacon->last_purged_snaps_scrub;
return true;
} else {
- return false;
+ return false; /* nothing to propose */
}
}
if (!cmdmap_from_json(m->cmd, &cmdmap, ss)) {
string rs = ss.str();
mon.reply_command(op, -EINVAL, rs, get_last_committed());
- return true;
+ return false; /* nothing to propose */
}
MonSession *session = op->get_session();
if (!session) {
derr << __func__ << " no session" << dendl;
mon.reply_command(op, -EACCES, "access denied", get_last_committed());
- return true;
+ return false; /* nothing to propose */
}
return prepare_command_impl(op, cmdmap);
{
op->mark_osdmon_event(__func__);
auto m = op->get_req<MMonCommand>();
- bool ret = false;
stringstream ss;
string rs;
bufferlist rdata;
(prefix == "osd crush set" && !osdid_present)) {
if (pending_inc.crush.length()) {
dout(10) << __func__ << " waiting for pending crush update " << dendl;
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
dout(10) << "prepare_command setting new crush map" << dendl;
bufferlist data(m->get_data());
catch (const std::exception &e) {
err = -EINVAL;
ss << "Failed to parse crushmap: " << e.what();
- goto reply;
+ goto reply_no_propose;
}
int64_t prior_version = 0;
<< dendl;
err = 0;
ss << osdmap.get_crush_version();
- goto reply;
+ goto reply_no_propose;
}
}
if (prior_version != osdmap.get_crush_version()) {
err = -EPERM;
ss << "prior_version " << prior_version << " != crush version "
<< osdmap.get_crush_version();
- goto reply;
+ goto reply_no_propose;
}
}
if (!validate_crush_against_features(&crush, ss)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
err = osdmap.validate_crush_rules(&crush, &ss);
if (err < 0) {
- goto reply;
+ goto reply_no_propose;
}
if (g_conf()->mon_osd_crush_smoke_test) {
<< ": " << ess.str() << dendl;
ss << "crush smoke test failed with " << r << ": " << ess.str();
err = r;
- goto reply;
+ goto reply_no_propose;
}
dout(10) << __func__ << " crush somke test duration: "
<< duration << ", result: " << ess.str() << dendl;
}
if (!validate_crush_against_features(&newcrush, ss)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon.get_quorum_con_features());
string device_class;
if (!cmd_getval(cmdmap, "class", device_class)) {
err = -EINVAL; // no value!
- goto reply;
+ goto reply_no_propose;
}
bool stop = false;
<< dendl;
err = newcrush.update_device_class(osd, device_class, name, &ss);
if (err < 0) {
- goto reply;
+ goto reply_no_propose;
}
if (err == 0 && !_have_pending_crush()) {
if (!stop) {
// ss has reason for failure
ss << ", unable to parse osd id:\"" << idvec[j] << "\". ";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
osds.insert(osd);
}
err = newcrush.remove_device_class(cct, osd, &ss);
if (err < 0) {
// ss has reason for failure
- goto reply;
+ goto reply_no_propose;
}
updated.insert(osd);
}
string device_class;
if (!cmd_getval(cmdmap, "class", device_class)) {
err = -EINVAL; // no value!
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.require_osd_release < ceph_release_t::luminous) {
ss << "you must complete the upgrade and 'ceph osd require-osd-release "
<< "luminous' before using crush device classes";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (!_have_pending_crush() &&
_get_stable_crush().class_exists(device_class)) {
ss << "class '" << device_class << "' already exists";
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
if (newcrush.class_exists(device_class)) {
string device_class;
if (!cmd_getval(cmdmap, "class", device_class)) {
err = -EINVAL; // no value!
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.require_osd_release < ceph_release_t::luminous) {
ss << "you must complete the upgrade and 'ceph osd require-osd-release "
<< "luminous' before using crush device classes";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (!osdmap.crush->class_exists(device_class)) {
err = 0;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
if (newcrush.class_is_in_use(class_id, &ts)) {
err = -EBUSY;
ss << "class '" << device_class << "' " << ts.str();
- goto reply;
+ goto reply_no_propose;
}
// check if class is used by any erasure-code-profiles
err = -EBUSY;
ss << "class '" << device_class
<< "' is still referenced by erasure-code-profile(s): " << referenced_by;
- goto reply;
+ goto reply_no_propose;
}
set<int> osds;
err = newcrush.remove_device_class(cct, p, &ss);
if (err < 0) {
// ss has reason for failure
- goto reply;
+ goto reply_no_propose;
}
}
if (err < 0) {
ss << "class '" << device_class << "' cannot be removed '"
<< cpp_strerror(err) << "'";
- goto reply;
+ goto reply_no_propose;
}
}
string srcname, dstname;
if (!cmd_getval(cmdmap, "srcname", srcname)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (!cmd_getval(cmdmap, "dstname", dstname)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
// so command is idempotent
ss << "already renamed to '" << dstname << "'";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.rename_class(srcname, dstname);
if (err < 0) {
ss << "fail to rename '" << srcname << "' to '" << dstname << "' : "
<< cpp_strerror(err);
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
if (!_have_pending_crush() &&
_get_stable_crush().name_exists(name)) {
ss << "bucket '" << name << "' already exists";
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
if (type < 0) {
ss << "type '" << typestr << "' does not exist";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (type == 0) {
ss << "type '" << typestr << "' is for devices, not buckets";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int bucketno;
err = newcrush.add_bucket(0, 0,
NULL, &bucketno);
if (err < 0) {
ss << "add_bucket error: '" << cpp_strerror(err) << "'";
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.set_item_name(bucketno, name);
if (err < 0) {
ss << "error setting bucket name to '" << name << "'";
- goto reply;
+ goto reply_no_propose;
}
if (!loc.empty()) {
err = newcrush.move_bucket(cct, bucketno, loc);
if (err < 0) {
ss << "error moving bucket '" << name << "' to location " << loc;
- goto reply;
+ goto reply_no_propose;
}
} else {
ss << "no need to move item id " << bucketno << " name '" << name
cmd_getval(cmdmap, "dstname", dstname);
err = crush_rename_bucket(srcname, dstname, &ss);
- if (err == -EALREADY) // equivalent to success for idempotency
- err = 0;
- if (err)
- goto reply;
- else
+ if (err) {
+ // equivalent to success for idempotency
+ if (err == -EALREADY) {
+ err = 0;
+ }
+ goto reply_no_propose;
+ } else {
goto update;
+ }
} else if (prefix == "osd crush weight-set create" ||
prefix == "osd crush weight-set create-compat") {
if (_have_pending_crush()) {
if (newcrush.has_non_straw2_buckets()) {
ss << "crush map contains one or more bucket(s) that are not straw2";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (prefix == "osd crush weight-set create") {
if (osdmap.require_min_compat_client != ceph_release_t::unknown &&
<< "Try 'ceph osd set-require-min-compat-client luminous' "
<< "before using the new interface";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
string poolname, mode;
cmd_getval(cmdmap, "pool", poolname);
if (pool < 0) {
ss << "pool '" << poolname << "' not found";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
cmd_getval(cmdmap, "mode", mode);
if (mode != "flat" && mode != "positional") {
ss << "unrecognized weight-set mode '" << mode << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
positions = mode == "flat" ? 1 : osdmap.get_pg_pool(pool)->get_size();
} else {
ss << "weight-set for pool '" << osdmap.get_pool_name(pool)
<< "' already created";
}
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon.get_quorum_con_features());
if (pool < 0) {
ss << "pool '" << poolname << "' not found";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
} else {
pool = CrushWrapper::DEFAULT_CHOOSE_ARGS;
if (pool < 0) {
ss << "pool '" << poolname << "' not found";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
if (!newcrush.have_choose_args(pool)) {
ss << "no weight-set for pool '" << poolname << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
auto arg_map = newcrush.choose_args_get(pool);
int positions = newcrush.get_choose_args_positions(arg_map);
if (weight.size() != (size_t)positions) {
ss << "must specify exact " << positions << " weight values";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
} else {
pool = CrushWrapper::DEFAULT_CHOOSE_ARGS;
if (!newcrush.have_choose_args(pool)) {
ss << "no backward-compatible weight-set";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
}
if (!newcrush.name_exists(item)) {
ss << "item '" << item << "' does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.choose_args_adjust_item_weightf(
cct,
weight,
&ss);
if (err < 0) {
- goto reply;
+ goto reply_no_propose;
}
err = 0;
pending_inc.crush.clear();
err = -ENOENT;
ss << osd_name
<< " does not exist. Create it before updating the crush map";
- goto reply;
+ goto reply_no_propose;
}
double weight;
ss << "unable to parse weight value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
string args;
ss << "unable to set item id " << osdid << " name '" << osd_name
<< "' weight " << weight << " at location " << loc
<< ": does not exist";
- goto reply;
+ goto reply_no_propose;
}
dout(5) << "adding/updating crush item id " << osdid << " name '"
}
if (err < 0)
- goto reply;
+ goto reply_no_propose;
if (err == 0 && !_have_pending_crush()) {
ss << action << " item id " << osdid << " name '" << osd_name
<< "' weight " << weight << " at location " << loc << ": no change";
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
err = -ENOENT;
ss << osd_name
<< " does not exist. create it before updating the crush map";
- goto reply;
+ goto reply_no_propose;
}
double weight;
ss << "unable to parse weight value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
string args;
if (!newcrush.name_exists(source)) {
ss << "source item " << source << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
if (!newcrush.name_exists(dest)) {
ss << "dest item " << dest << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
int sid = newcrush.get_item_id(source);
int did = newcrush.get_item_id(dest);
if (newcrush.get_immediate_parent_id(sid, &sparent) == 0 && !force) {
ss << "source item " << source << " is not an orphan bucket; pass --yes-i-really-mean-it to proceed anyway";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (newcrush.get_bucket_alg(sid) != newcrush.get_bucket_alg(did) &&
!force) {
<< "dest bucket alg " << crush_alg_name(newcrush.get_bucket_alg(did))
<< "; pass --yes-i-really-mean-it to proceed anyway";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
int r = newcrush.swap_bucket(cct, sid, did);
if (r < 0) {
ss << "failed to swap bucket contents: " << cpp_strerror(r);
err = r;
- goto reply;
+ goto reply_no_propose;
}
ss << "swapped bucket of " << source << " to " << dest;
pending_inc.crush.clear();
if (!osdmap.crush->name_exists(name)) {
err = -ENOENT;
ss << "item " << name << " does not exist";
- goto reply;
+ goto reply_no_propose;
} else {
dout(5) << "resolved crush name '" << name << "' to id " << id << dendl;
}
ss << "no need to move item id " << id << " name '" << name
<< "' to location " << loc << " in crush map";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
dout(5) << "linking crush item name '" << name << "' at location " << loc << dendl;
if (!newcrush.name_exists(name)) {
err = -ENOENT;
ss << "item " << name << " does not exist";
- goto reply;
+ goto reply_no_propose;
} else {
int id = newcrush.get_item_id(name);
if (!newcrush.check_item_loc(cct, id, loc, (int *)NULL)) {
} else {
ss << "cannot link item id " << id << " name '" << name
<< "' to location " << loc;
- goto reply;
+ goto reply_no_propose;
}
} else {
ss << "no need to move item id " << id << " name '" << name
if (!newcrush.name_exists(name)) {
err = -ENOENT;
ss << "device '" << name << "' does not appear in the crush map";
- goto reply;
+ goto reply_no_propose;
}
int id = newcrush.get_item_id(name);
if (id < 0) {
ss << "device '" << name << "' is not a leaf in the crush map";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
double w;
if (!cmd_getval(cmdmap, "weight", w)) {
ss << "unable to parse weight value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.adjust_item_weightf(cct, id, w,
g_conf()->osd_crush_update_weight_set);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon.get_quorum_con_features());
ss << "reweighted item id " << id << " name '" << name << "' to " << w
if (!newcrush.name_exists(name)) {
err = -ENOENT;
ss << "device '" << name << "' does not appear in the crush map";
- goto reply;
+ goto reply_no_propose;
}
int id = newcrush.get_item_id(name);
if (id >= 0) {
ss << "device '" << name << "' is not a subtree in the crush map";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
double w;
if (!cmd_getval(cmdmap, "weight", w)) {
ss << "unable to parse weight value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.adjust_subtree_weightf(cct, id, w,
g_conf()->osd_crush_update_weight_set);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon.get_quorum_con_features());
ss << "reweighted subtree id " << id << " name '" << name << "' to " << w
} else {
ss << "unrecognized profile '" << profile << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (!validate_crush_against_features(&newcrush, ss)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
err = -EINVAL;
ss << "failed to parse integer value "
<< cmd_vartype_stringify(cmdmap.at("value"));
- goto reply;
+ goto reply_no_propose;
}
if (tunable == "straw_calc_version") {
if (value != 0 && value != 1) {
ss << "value must be 0 or 1; got " << value;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
newcrush.set_straw_calc_version(value);
} else {
ss << "unrecognized tunable '" << tunable << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (!validate_crush_against_features(&newcrush, ss)) {
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
// From the user point of view, the rule is more meaningfull.
ss << "rule " << name << " already exists";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
pg_pool_t::TYPE_REPLICATED, &ss);
if (ruleno < 0) {
err = ruleno;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
// From the user point of view, the rule is more meaningfull.
ss << "rule " << name << " already exists";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
"firstn", pg_pool_t::TYPE_REPLICATED, &ss);
if (ruleno < 0) {
err = ruleno;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
if (erasure_code_profile_in_use(osdmap.pools, name, &ss)) {
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.has_erasure_code_profile(name) ||
} else {
ss << "erasure-code-profile " << name << " does not exist";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
} else if (prefix == "osd erasure-code-profile set") {
map<string,string> profile_map;
err = parse_erasure_code_profile(profile, &profile_map, &ss);
if (err)
- goto reply;
+ goto reply_no_propose;
if (auto found = profile_map.find("crush-failure-domain");
found != profile_map.end()) {
const auto& failure_domain = found->second;
ss << "erasure-code-profile " << profile_map
<< " contains an invalid failure-domain " << std::quoted(failure_domain);
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
}
ss << "erasure-code-profile " << profile_map
<< " must contain a plugin entry" << std::endl;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
string plugin = profile_map["plugin"];
} else {
err = normalize_profile(name, profile_map, force, &ss);
if (err)
- goto reply;
+ goto reply_no_propose;
if (osdmap.has_erasure_code_profile(name)) {
ErasureCodeProfile existing_profile_map =
osdmap.get_erasure_code_profile(name);
err = normalize_profile(name, existing_profile_map, force, &ss);
if (err)
- goto reply;
+ goto reply_no_propose;
if (existing_profile_map == profile_map) {
err = 0;
- goto reply;
+ goto reply_no_propose;
}
if (!force) {
err = -EPERM;
<< existing_profile_map
<< " is different from the proposed profile "
<< profile_map;
- goto reply;
+ goto reply_no_propose;
}
}
if (err == -EAGAIN)
goto wait;
if (err)
- goto reply;
+ goto reply_no_propose;
string name, poolstr;
cmd_getval(cmdmap, "name", name);
string profile;
profile_map,
&ss);
if (err)
- goto reply;
+ goto reply_no_propose;
err = normalize_profile(name, profile_map, true, &ss);
if (err)
- goto reply;
+ goto reply_no_propose;
dout(20) << "erasure code profile set " << profile << "="
<< profile_map << dendl;
pending_inc.set_erasure_code_profile(profile, profile_map);
case -EEXIST: // return immediately
ss << "rule " << name << " already exists";
err = 0;
- goto reply;
- break;
+ goto reply_no_propose;
case -EALREADY: // wait for pending to be proposed
ss << "rule " << name << " already exists";
err = 0;
break;
default: // non recoverable error
- goto reply;
- break;
+ goto reply_no_propose;
}
} else {
ss << "created rule " << name << " at " << rule;
if (!osdmap.crush->rule_exists(name)) {
ss << "rule " << name << " does not exist";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
if (osdmap.crush_rule_in_use(ruleno)) {
ss << "crush rule " << name << " (" << ruleno << ") is in use";
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.remove_rule(ruleno);
if (err < 0) {
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
if (srcname.empty() || dstname.empty()) {
ss << "must specify both source rule name and destination rule name";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (srcname == dstname) {
ss << "destination rule name is equal to source rule name";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
CrushWrapper newcrush = _get_pending_crush();
// (so this command is idempotent)
ss << "already renamed to '" << dstname << "'";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
err = newcrush.rename_rule(srcname, dstname, &ss);
if (err < 0) {
// ss has reason for failure
- goto reply;
+ goto reply_no_propose;
}
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon.get_quorum_con_features());
ss << "unable to parse 'newmax' value '"
<< cmd_vartype_stringify(cmdmap.at("newmax")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (newmax > g_conf()->mon_max_osd) {
err = -ERANGE;
ss << "cannot set max_osd to " << newmax << " which is > conf.mon_max_osd ("
<< g_conf()->mon_max_osd << ")";
- goto reply;
+ goto reply_no_propose;
}
// Don't allow shrinking OSD number as this will cause data loss
err = -EBUSY;
ss << "cannot shrink max_osd to " << newmax
<< " because osd." << i << " (and possibly others) still in use";
- goto reply;
+ goto reply_no_propose;
}
}
}
ss << "unable to parse 'ratio' value '"
<< cmd_vartype_stringify(cmdmap.at("ratio")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (prefix == "osd set-full-ratio")
pending_inc.new_full_ratio = n;
if (!vno) {
ss << "version " << v << " is not recognized";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
OSDMap newmap;
newmap.deepish_copy_from(osdmap);
ss << "osdmap current utilizes features that require " << mvno
<< "; cannot set require_min_compat_client below that to " << vno;
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
bool sure = false;
cmd_getval(cmdmap, "yes_i_really_mean_it", sure);
if (!ok) {
ss << "; add --yes-i-really-mean-it to do it anyway";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
}
ss << "set require_min_compat_client to " << vno;
ss << "Not advisable to continue since no OSDs are up. Pass "
<< "--yes-i-really-mean-it if you really wish to continue.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
// The release check here is required because for OSD_PGLOG_HARDLIMIT,
// we are reusing a jewel feature bit that was retired in luminous.
} else {
ss << "not all up OSDs have OSD_PGLOG_HARDLIMIT feature";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
+ } else if (key == "noautoscale") {
+ return prepare_set_flag(op, CEPH_OSDMAP_NOAUTOSCALE);
} else {
ss << "unrecognized flag '" << key << "'";
err = -EINVAL;
return prepare_unset_flag(op, CEPH_OSDMAP_NOTIERAGENT);
else if (key == "nosnaptrim")
return prepare_unset_flag(op, CEPH_OSDMAP_NOSNAPTRIM);
+ else if (key == "noautoscale")
+ return prepare_unset_flag(op, CEPH_OSDMAP_NOAUTOSCALE);
else {
ss << "unrecognized flag '" << key << "'";
err = -EINVAL;
if (!rel) {
ss << "unrecognized release " << release;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (rel == osdmap.require_osd_release) {
// idempotent
err = 0;
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.require_osd_release < ceph_release_t::pacific && !sure) {
ss << "Not advisable to continue since current 'require_osd_release' "
<< "refers to a very old Ceph release. Pass "
<< "--yes-i-really-mean-it if you really wish to continue.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (!osdmap.get_num_up_osds() && !sure) {
ss << "Not advisable to continue since no OSDs are up. Pass "
<< "--yes-i-really-mean-it if you really wish to continue.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (rel == ceph_release_t::pacific) {
if (!mon.monmap->get_required_features().contains_all(
ceph::features::mon::FEATURE_PACIFIC)) {
ss << "not all mons are pacific";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if ((!HAVE_FEATURE(osdmap.get_up_osd_features(), SERVER_PACIFIC))
&& !sure) {
ss << "not all up OSDs have CEPH_FEATURE_SERVER_PACIFIC feature";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
} else if (rel == ceph_release_t::quincy) {
if (!mon.monmap->get_required_features().contains_all(
ceph::features::mon::FEATURE_QUINCY)) {
ss << "not all mons are quincy";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if ((!HAVE_FEATURE(osdmap.get_up_osd_features(), SERVER_QUINCY))
&& !sure) {
ss << "not all up OSDs have CEPH_FEATURE_SERVER_QUINCY feature";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
} else if (rel == ceph_release_t::reef) {
if (!mon.monmap->get_required_features().contains_all(
ceph::features::mon::FEATURE_REEF)) {
ss << "not all mons are reef";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if ((!HAVE_FEATURE(osdmap.get_up_osd_features(), SERVER_REEF))
&& !sure) {
ss << "not all up OSDs have CEPH_FEATURE_SERVER_REEF feature";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
} else {
ss << "not supported for this release";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (rel < osdmap.require_osd_release) {
ss << "require_osd_release cannot be lowered once it has been set";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_require_osd_release = rel;
goto update;
ss << "unrecognized flag '" << f << "', must be one of "
<< "{noup,nodown,noin,noout}";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
}
} else {
if (flags == 0) {
ss << "must specify flag(s) {noup,nodwon,noin,noout} to set/unset";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (who.empty()) {
ss << "must specify at least one or more targets to set/unset";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
set<int> osds;
set<int> crush_nodes;
if (osds.empty() && crush_nodes.empty() && device_classes.empty()) {
// ss has reason for failure
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
bool any = false;
for (auto osd : osds) {
pg_t pgid;
err = parse_pgid(cmdmap, ss, pgid);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
if (pending_inc.new_pg_temp.count(pgid)) {
dout(10) << __func__ << " waiting for pending update on " << pgid << dendl;
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
vector<int64_t> id_vec;
if (!osdmap.exists(osd)) {
ss << "osd." << osd << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
new_pg_temp.push_back(osd);
}
ss << "num of osds (" << new_pg_temp.size() <<") < pool min size ("
<< pool_min_size << ")";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int pool_size = osdmap.get_pg_pool_size(pgid);
ss << "num of osds (" << new_pg_temp.size() <<") > pool size ("
<< pool_size << ")";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_pg_temp[pgid] = mempool::osdmap::vector<int>(
pg_t pgid;
err = parse_pgid(cmdmap, ss, pgid);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
int64_t osd;
if (prefix == "osd primary-temp") {
ss << "unable to parse 'id' value '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (!osdmap.exists(osd)) {
ss << "osd." << osd << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
}
else if (prefix == "osd rm-primary-temp") {
<< osdmap.require_min_compat_client
<< " < firefly, which is required for primary-temp";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_primary_temp[pgid] = osd;
pg_t pgid;
err = parse_pgid(cmdmap, ss, pgid);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
vector<int> acting;
int primary;
osdmap.pg_to_acting_osds(pgid, &acting, &primary);
if (primary < 0) {
err = -EAGAIN;
ss << "pg currently has no primary";
- goto reply;
+ goto reply_no_propose;
}
if (acting.size() > 1) {
// map to just primary; it will map back to what it wants
if (!done) {
err = -EAGAIN;
ss << "not enough up OSDs in the cluster to force repeer";
- goto reply;
+ goto reply_no_propose;
}
}
goto update;
<< "Try 'ceph osd set-require-min-compat-client " << min_release_name << "' "
<< "before using the new interface";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
//TODO: Should I add feature and test for upmap-primary?
if (err == -EAGAIN)
goto wait;
if (err < 0)
- goto reply;
+ goto reply_no_propose;
pg_t pgid;
err = parse_pgid(cmdmap, ss, pgid);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
if (pending_inc.old_pools.count(pgid.pool())) {
ss << "pool of " << pgid << " is pending removal";
err = -ENOENT;
pending_inc.old_pg_upmap.count(pgid)) {
dout(10) << __func__ << " waiting for pending update on "
<< pgid << dendl;
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
break;
if (! pt->is_replicated()) {
ss << "pg-upmap-primary is only supported for replicated pools";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
}
// fall through
pending_inc.old_pg_upmap_items.count(pgid)) {
dout(10) << __func__ << " waiting for pending update on "
<< pgid << dendl;
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
break;
ss << "unable to parse 'id' value(s) '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int pool_min_size = osdmap.get_pg_pool_min_size(pgid);
ss << "num of osds (" << id_vec.size() <<") < pool min size ("
<< pool_min_size << ")";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int pool_size = osdmap.get_pg_pool_size(pgid);
ss << "num of osds (" << id_vec.size() <<") > pool size ("
<< pool_size << ")";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
vector<int32_t> new_pg_upmap;
if (osd != CRUSH_ITEM_NONE && !osdmap.exists(osd)) {
ss << "osd." << osd << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
auto it = std::find(new_pg_upmap.begin(), new_pg_upmap.end(), osd);
if (it != new_pg_upmap.end()) {
if (new_pg_upmap.empty()) {
ss << "no valid upmap items(pairs) is specified";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_pg_upmap[pgid] = mempool::osdmap::vector<int32_t>(
ss << "unable to parse 'id' value(s) '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (id_vec.size() % 2) {
ss << "you must specify pairs of osd ids to be remapped";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int pool_size = osdmap.get_pg_pool_size(pgid);
ss << "num of osd pairs (" << id_vec.size() / 2 <<") > pool size ("
<< pool_size << ")";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
vector<pair<int32_t,int32_t>> new_pg_upmap_items;
if (!osdmap.exists(from)) {
ss << "osd." << from << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
if (to != CRUSH_ITEM_NONE && !osdmap.exists(to)) {
ss << "osd." << to << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
pair<int32_t,int32_t> entry = make_pair(from, to);
auto it = std::find(new_pg_upmap_items.begin(),
if (new_pg_upmap_items.empty()) {
ss << "no valid upmap items(pairs) is specified";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_pg_upmap_items[pgid] =
ss << "invalid osd id value '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (id != CRUSH_ITEM_NONE && !osdmap.exists(id)) {
ss << "osd." << id << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
vector<int> acting;
int primary;
if (id == primary) {
ss << "osd." << id << " is already primary for pg " << pgid;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
int found_idx = 0;
for (int i = 1 ; i < (int)acting.size(); i++) { // skip 0 on purpose
if (found_idx == 0) {
ss << "osd." << id << " is not in acting set for pg " << pgid;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
vector<int> new_acting(acting);
new_acting[found_idx] = new_acting[0];
ss << "can't change primary for pg " << pgid << " to osd." << id
<< " - illegal pg after the change";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_pg_upmap_primary[pgid] = id;
//TO-REMOVE:
ss << "invalid osd id value '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
double w;
if (!cmd_getval(cmdmap, "weight", w)) {
ss << "unable to parse 'weight' value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
long ww = (int)((double)CEPH_OSD_MAX_PRIMARY_AFFINITY*w);
if (ww < 0L) {
ss << "weight must be >= 0";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.require_min_compat_client != ceph_release_t::unknown &&
osdmap.require_min_compat_client < ceph_release_t::firefly) {
<< osdmap.require_min_compat_client
<< " < firefly, which is required for primary-affinity";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.exists(id)) {
pending_inc.new_primary_affinity[id] = ww;
} else {
ss << "osd." << id << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
} else if (prefix == "osd reweight") {
int64_t id;
ss << "unable to parse osd id value '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
double w;
if (!cmd_getval(cmdmap, "weight", w)) {
ss << "unable to parse weight value '"
<< cmd_vartype_stringify(cmdmap.at("weight")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
long ww = (int)((double)CEPH_OSD_IN*w);
if (ww < 0L) {
ss << "weight must be >= 0";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (osdmap.exists(id)) {
pending_inc.new_weight[id] = ww;
} else {
ss << "osd." << id << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
} else if (prefix == "osd reweightn") {
map<int32_t, uint32_t> weights;
if (err) {
ss << "unable to parse 'weights' value '"
<< cmd_vartype_stringify(cmdmap.at("weights")) << "'";
- goto reply;
+ goto reply_no_propose;
}
pending_inc.new_weight.insert(weights.begin(), weights.end());
wait_for_finished_proposal(
ss << "unable to parse osd id value '"
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
bool sure = false;
cmd_getval(cmdmap, "yes_i_really_mean_it", sure);
ss << "are you SURE? this might mean real, permanent data loss. pass "
"--yes-i-really-mean-it if you really do.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
} else if (!osdmap.exists(id)) {
ss << "osd." << id << " does not exist";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
} else if (!osdmap.is_down(id)) {
ss << "osd." << id << " is not down";
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
} else {
epoch_t e = osdmap.get_info(id).down_at;
pending_inc.new_lost[id] = e;
<< cmd_vartype_stringify(cmdmap.at("id")) << "";
}
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
bool is_destroy = (prefix == "osd destroy-actual");
<< "as deletion of cephx and lockbox keys. "
<< "Pass --yes-i-really-mean-it if you really do.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
} else if (!osdmap.exists(id)) {
ss << "osd." << id << " does not exist";
err = 0; // idempotent
- goto reply;
+ goto reply_no_propose;
} else if (osdmap.is_up(id)) {
ss << "osd." << id << " is not `down`.";
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
} else if (is_destroy && osdmap.is_destroyed(id)) {
ss << "destroyed osd." << id;
err = 0;
- goto reply;
+ goto reply_no_propose;
}
if (prefix == "osd purge-new" &&
(osdmap.get_state(id) & CEPH_OSD_NEW) == 0) {
ss << "osd." << id << " is not new";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
bool goto_reply = false;
paxos.unplug();
if (err < 0 || goto_reply) {
- goto reply;
+ goto reply_no_propose;
}
if (is_destroy) {
err = get_json_str_map(param_json, ss, ¶m_map);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
dout(20) << __func__ << " osd new params " << param_map << dendl;
paxos.unplug();
if (err < 0) {
- goto reply;
+ goto reply_no_propose;
}
if (f) {
if (err == EEXIST) {
// idempotent operation
err = 0;
- goto reply;
+ goto reply_no_propose;
}
wait_for_finished_proposal(op,
if (cmd_id < 0) {
ss << "invalid osd id value '" << cmd_id << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
dout(10) << " osd create got id " << cmd_id << dendl;
}
if (!uuid.parse(uuidstr.c_str())) {
ss << "invalid uuid value '" << uuidstr << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
// we only care about the id if we also have the uuid, to
// ensure the operation's idempotency.
err = prepare_command_osd_create(id, uuid, &new_id, ss);
if (err < 0) {
if (err == -EAGAIN) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
// a check has failed; reply to the user.
- goto reply;
+ goto reply_no_propose;
} else if (err == EEXIST) {
// this is an idempotent operation; we can go ahead and reply.
rdata.append(ss);
}
err = 0;
- goto reply;
+ goto reply_no_propose;
}
string empty_device_class;
} else {
ss << "Did you mean to specify \"osd blocklist range\"?";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
}
entity_addr_t addr;
if (!addr.parse(addrstr)) {
ss << "unable to parse address " << addrstr;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
else {
if (range) {
ss << "You specified a range command, but " << addr
<< " does not parse as a CIDR range";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
addr.type = entity_addr_t::TYPE_CIDR;
err = check_cluster_features(CEPH_FEATUREMASK_RANGE_BLOCKLIST, ss);
if (err) {
- goto reply;
+ goto reply_no_propose;
}
if ((addr.is_ipv4() && addr.get_nonce() > 32) ||
(addr.is_ipv6() && addr.get_nonce() > 128)) {
ss << "Too many bits in range for that protocol!";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
} else {
if (osdmap.require_osd_release >= ceph_release_t::nautilus) {
}
ss << addr << " isn't blocklisted";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
}
} else if (prefix == "osd pool mksnap") {
if (pool < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string snapname;
cmd_getval(cmdmap, "snap", snapname);
if (p->is_unmanaged_snaps_mode()) {
ss << "pool " << poolstr << " is in unmanaged snaps mode";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
} else if (p->snap_exists(snapname.c_str())) {
ss << "pool " << poolstr << " snap " << snapname << " already exists";
err = 0;
- goto reply;
+ goto reply_no_propose;
} else if (p->is_tier()) {
ss << "pool " << poolstr << " is a cache tier";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pg_pool_t *pp = 0;
if (pending_inc.new_pools.count(pool))
dout(20) << "pool-level snapshots have been disabled for pools "
"attached to an fs - poolid:" << pool << dendl;
err = -EOPNOTSUPP;
- goto reply;
+ goto reply_no_propose;
}
pp->add_snap(snapname.c_str(), ceph_clock_now());
pp->set_snap_epoch(pending_inc.epoch);
if (pool < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string snapname;
cmd_getval(cmdmap, "snap", snapname);
if (p->is_unmanaged_snaps_mode()) {
ss << "pool " << poolstr << " is in unmanaged snaps mode";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
} else if (!p->snap_exists(snapname.c_str())) {
ss << "pool " << poolstr << " snap " << snapname << " does not exist";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
pg_pool_t *pp = 0;
if (pending_inc.new_pools.count(pool))
if (poolstr[0] == '.' && !confirm) {
ss << "pool names beginning with . are not allowed";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
if (pool_id >= 0) {
ss << "pool '" << poolstr << "' already exists";
err = 0;
}
- goto reply;
+ goto reply_no_propose;
}
int pool_type;
} else {
ss << "unknown pool type '" << pool_type_str << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
bool implicit_rule_creation = false;
profile_map,
&ss);
if (err)
- goto reply;
+ goto reply_no_propose;
dout(20) << "erasure code profile " << erasure_code_profile << " set" << dendl;
pending_inc.set_erasure_code_profile(erasure_code_profile, profile_map);
goto wait;
if (interr.length()) {
ss << "error parsing integer value '" << rule_name << "': " << interr;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
}
rule_name = erasure_code_profile;
int rule;
err = get_crush_rule(rule_name, &rule, &ss);
if (err == -EAGAIN) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
if (err)
- goto reply;
+ goto reply_no_propose;
}
if (expected_num_objects < 0) {
ss << "'expected_num_objects' must be non-negative";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
set<int32_t> osds;
cct->_conf->filestore_merge_threshold > 0) {
ss << "'expected_num_objects' requires 'filestore_merge_threshold < 0'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (has_filestore_osd &&
<< "expected_num_objects parameter when creating the pool."
<< " Pass --yes-i-really-mean-it to ignore it";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
}
switch(err) {
case -EEXIST:
ss << "pool '" << poolstr << "' already exists";
- break;
+ err = 0;
+ goto reply_no_propose;
case -EAGAIN:
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
case -ERANGE:
- goto reply;
+ goto reply_no_propose;
default:
- goto reply;
- break;
+ goto reply_no_propose;
}
} else {
ss << "pool '" << poolstr << "' created";
if (pool < 0) {
ss << "pool '" << poolstr << "' does not exist";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
bool force_no_fake = false;
<< ". If you are *ABSOLUTELY CERTAIN* that is what you want, pass the pool name *twice*, "
<< "followed by --yes-i-really-really-mean-it.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
err = _prepare_remove_pool(pool, &ss, force_no_fake);
if (err == -EAGAIN) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
if (err < 0)
- goto reply;
+ goto reply_no_propose;
goto update;
} else if (prefix == "osd pool rename") {
string srcpoolstr, destpoolstr;
if (destpoolstr[0] == '.' && !confirm) {
ss << "pool names beginning with . are not allowed";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
if (pool_src < 0) {
if (pool_dst >= 0) {
ss << "unrecognized pool '" << srcpoolstr << "'";
err = -ENOENT;
}
- goto reply;
+ goto reply_no_propose;
} else if (pool_dst >= 0) {
// source pool exists and so does the destination pool
ss << "pool '" << destpoolstr << "' already exists";
err = -EEXIST;
- goto reply;
+ goto reply_no_propose;
}
int ret = _prepare_rename_pool(pool_src, destpoolstr);
if (err == -EAGAIN)
goto wait;
if (err < 0)
- goto reply;
+ goto reply_no_propose;
getline(ss, rs);
wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs,
if (err == -EAGAIN)
goto wait;
if (err)
- goto reply;
+ goto reply_no_propose;
string poolstr;
cmd_getval(cmdmap, "pool", poolstr);
int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string tierpoolstr;
cmd_getval(cmdmap, "tierpool", tierpoolstr);
if (tierpool_id < 0) {
ss << "unrecognized pool '" << tierpoolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
ceph_assert(tp);
if (!_check_become_tier(tierpool_id, tp, pool_id, p, &err, &ss)) {
- goto reply;
+ goto reply_no_propose;
}
// make sure new tier is empty
!force_nonempty) {
ss << "tier pool '" << tierpoolstr << "' is not empty; --force-nonempty to force";
err = -ENOTEMPTY;
- goto reply;
+ goto reply_no_propose;
}
if (tp->is_erasure()) {
ss << "tier pool '" << tierpoolstr
<< "' is an ec pool, which cannot be a tier";
err = -ENOTSUP;
- goto reply;
+ goto reply_no_propose;
}
if ((!tp->removed_snaps.empty() || !tp->snaps.empty()) &&
(!force_nonempty ||
!g_conf()->mon_debug_unsafe_allow_tier_with_nonempty_snaps)) {
ss << "tier pool '" << tierpoolstr << "' has snapshot state; it cannot be added as a tier without breaking the pool";
err = -ENOTEMPTY;
- goto reply;
+ goto reply_no_propose;
}
// go
pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
pg_pool_t *ntp = pending_inc.get_new_pool(tierpool_id, tp);
if (np->tiers.count(tierpool_id) || ntp->is_tier()) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
np->tiers.insert(tierpool_id);
np->set_snap_epoch(pending_inc.epoch); // tier will update to our snap info
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string tierpoolstr;
cmd_getval(cmdmap, "tierpool", tierpoolstr);
if (tierpool_id < 0) {
ss << "unrecognized pool '" << tierpoolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
ceph_assert(tp);
if (!_check_remove_tier(pool_id, p, tp, &err, &ss)) {
- goto reply;
+ goto reply_no_propose;
}
if (p->tiers.count(tierpool_id) == 0) {
ss << "pool '" << tierpoolstr << "' is now (or already was) not a tier of '" << poolstr << "'";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
if (tp->tier_of != pool_id) {
ss << "tier pool '" << tierpoolstr << "' is a tier of '"
// be scary about it; this is an inconsistency and bells must go off
<< "THIS SHOULD NOT HAVE HAPPENED AT ALL";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (p->read_tier == tierpool_id) {
ss << "tier pool '" << tierpoolstr << "' is the overlay for '" << poolstr << "'; please remove-overlay first";
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
}
// go
pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
if (np->tiers.count(tierpool_id) == 0 ||
ntp->tier_of != pool_id ||
np->read_tier == tierpool_id) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
np->tiers.erase(tierpool_id);
ntp->clear_tier();
if (err == -EAGAIN)
goto wait;
if (err)
- goto reply;
+ goto reply_no_propose;
string poolstr;
cmd_getval(cmdmap, "pool", poolstr);
int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string overlaypoolstr;
cmd_getval(cmdmap, "overlaypool", overlaypoolstr);
if (overlaypool_id < 0) {
ss << "unrecognized pool '" << overlaypoolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
if (p->tiers.count(overlaypool_id) == 0) {
ss << "tier pool '" << overlaypoolstr << "' is not a tier of '" << poolstr << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if (p->read_tier == overlaypool_id) {
err = 0;
ss << "overlay for '" << poolstr << "' is now (or already was) '" << overlaypoolstr << "'";
- goto reply;
+ goto reply_no_propose;
}
if (p->has_read_tier()) {
ss << "pool '" << poolstr << "' has overlay '"
<< osdmap.get_pool_name(p->read_tier)
<< "'; please remove-overlay first";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
// go
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
if (!p->has_read_tier()) {
err = 0;
ss << "there is now (or already was) no overlay for '" << poolstr << "'";
- goto reply;
+ goto reply_no_propose;
}
if (!_check_remove_tier(pool_id, p, NULL, &err, &ss)) {
- goto reply;
+ goto reply_no_propose;
}
// go
if (err == -EAGAIN)
goto wait;
if (err)
- goto reply;
+ goto reply_no_propose;
string poolstr;
cmd_getval(cmdmap, "pool", poolstr);
int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
if (!p->is_tier()) {
ss << "pool '" << poolstr << "' is not a tier";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
string modestr;
cmd_getval(cmdmap, "mode", modestr);
if (int(mode) < 0) {
ss << "'" << modestr << "' is not a valid cache mode";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
bool sure = false;
mode == pg_pool_t::CACHEMODE_READFORWARD) {
ss << "'" << modestr << "' is no longer a supported cache mode";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
if ((mode != pg_pool_t::CACHEMODE_WRITEBACK &&
mode != pg_pool_t::CACHEMODE_NONE &&
ss << "'" << modestr << "' is not a well-supported cache mode and may "
<< "corrupt your data. pass --yes-i-really-mean-it to force.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
// pool already has this cache-mode set and there are no pending changes
ss << "set cache-mode for pool '" << poolstr << "'"
<< " to " << pg_pool_t::get_cache_mode_name(mode);
err = 0;
- goto reply;
+ goto reply_no_propose;
}
/* Mode description:
<< pg_pool_t::get_cache_mode_name(pg_pool_t::CACHEMODE_READPROXY)
<< "' allowed.";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
if ((p->cache_mode == pg_pool_t::CACHEMODE_READFORWARD &&
(mode != pg_pool_t::CACHEMODE_WRITEBACK &&
<< pg_pool_t::get_cache_mode_name(mode) << "' on pool '" << poolstr
<< "': dirty objects found";
err = -EBUSY;
- goto reply;
+ goto reply_no_propose;
}
}
// go
if (err == -EAGAIN)
goto wait;
if (err)
- goto reply;
+ goto reply_no_propose;
string poolstr;
cmd_getval(cmdmap, "pool", poolstr);
int64_t pool_id = osdmap.lookup_pg_pool_name(poolstr);
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string tierpoolstr;
cmd_getval(cmdmap, "tierpool", tierpoolstr);
if (tierpool_id < 0) {
ss << "unrecognized pool '" << tierpoolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
const pg_pool_t *p = osdmap.get_pg_pool(pool_id);
ceph_assert(p);
ceph_assert(tp);
if (!_check_become_tier(tierpool_id, tp, pool_id, p, &err, &ss)) {
- goto reply;
+ goto reply_no_propose;
}
int64_t size = 0;
ss << "unable to parse 'size' value '"
<< cmd_vartype_stringify(cmdmap.at("size")) << "'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
// make sure new tier is empty
const pool_stat_t *pstats =
if (pstats && pstats->stats.sum.num_objects != 0) {
ss << "tier pool '" << tierpoolstr << "' is not empty";
err = -ENOTEMPTY;
- goto reply;
+ goto reply_no_propose;
}
auto& modestr = g_conf().get_val<string>("osd_tier_default_cache_mode");
pg_pool_t::cache_mode_t mode = pg_pool_t::get_cache_mode_from_str(modestr);
if (int(mode) < 0) {
ss << "osd tier cache default mode '" << modestr << "' is not a valid cache mode";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
HitSet::Params hsp;
auto& cache_hit_set_type =
ss << "osd tier cache default hit set type '"
<< cache_hit_set_type << "' is not a known type";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
// go
pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
pg_pool_t *ntp = pending_inc.get_new_pool(tierpool_id, tp);
if (np->tiers.count(tierpool_id) || ntp->is_tier()) {
- wait_for_finished_proposal(op, new C_RetryMessage(this, op));
- return true;
+ goto wait;
}
np->tiers.insert(tierpool_id);
np->read_tier = np->write_tier = tierpool_id;
if (pool_id < 0) {
ss << "unrecognized pool '" << poolstr << "'";
err = -ENOENT;
- goto reply;
+ goto reply_no_propose;
}
string field;
if (field != "max_objects" && field != "max_bytes") {
ss << "unrecognized field '" << field << "'; should be 'max_bytes' or 'max_objects'";
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
// val could contain unit designations, so we treat as a string
if (!tss.empty()) {
ss << "error parsing value '" << val << "': " << tss;
err = -EINVAL;
- goto reply;
+ goto reply_no_propose;
}
pg_pool_t *pi = pending_inc.get_new_pool(pool_id, osdmap.get_pg_pool(pool_id));
if (err == -EAGAIN) {
goto wait;
} else if (err < 0) {
- goto reply;
+ goto reply_no_propose;
} else {
goto update;
}
string pgidstr;
err = parse_pgid(cmdmap, ss, pgid, pgidstr);
if (err < 0)
- goto reply;
+ goto reply_no_propose;
bool sure = false;
cmd_getval(cmdmap, "yes_i_really_mean_it", sure);
if (!sure) {
<< "willing to accept that the data is permanently destroyed. Pass "
<< "--yes-i-really-mean-it to proceed.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
bool creating_now;
{
} else {
ss << "pg " << pgid << " already creating";
err = 0;
- goto reply;
+ goto reply_no_propose;
}
} else if (prefix == "osd force_healthy_stretch_mode") {
bool sure = false;
"(probably two data centers or availability zones?) and may result in PGs "
"going inactive until backfilling is complete. Pass --yes-i-really-mean-it to proceed.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
try_end_recovery_stretch_mode(true);
ss << "Triggering healthy stretch mode";
err = 0;
- goto reply;
+ goto reply_no_propose;
} else if (prefix == "osd force_recovery_stretch_mode") {
bool sure = false;
cmd_getval(cmdmap, "yes_i_really_mean_it", sure);
"availability zones?) and should have happened automatically"
"Pass --yes-i-really-mean-it to proceed.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
mon.go_recovery_stretch_mode();
ss << "Triggering recovery stretch mode";
err = 0;
- goto reply;
+ goto reply_no_propose;
} else if (prefix == "osd set-allow-crimson") {
bool sure = false;
<< "If you are sure, add --yes-i-really-mean-it and add 'crimson' to "
<< "the experimental features config. This setting is irrevocable.";
err = -EPERM;
- goto reply;
+ goto reply_no_propose;
}
err = 0;
if (osdmap.get_allow_crimson()) {
- goto reply;
+ goto reply_no_propose;
} else {
pending_inc.set_allow_crimson();
goto update;
err = -EINVAL;
}
- reply:
+ reply_no_propose:
getline(ss, rs);
if (err < 0 && rs.length() == 0)
rs = cpp_strerror(err);
mon.reply_command(op, err, rs, rdata, get_last_committed());
- return ret;
+ return false; /* nothing to propose */
update:
getline(ss, rs);
return true;
wait:
+ // XXX
+ // Some osd commands split changes across two epochs.
+ // It seems this is mostly for crush rule changes. It doesn't need
+ // to be this way but it's a bit of work to fix that. For now,
+ // trigger a proposal by returning true and then retry the command
+ // to complete the operation.
wait_for_finished_proposal(op, new C_RetryMessage(this, op));
return true;
}