mirror of
https://github.com/ceph/ceph
synced 2025-02-22 10:37:15 +00:00
osd, mon: Add 'osd pg-upmap-primary' and 'osd rm-pg-upmap-primary' commands.
Changed OSDMap to keep upmap-primary records The upmap-primary records are visible in json/xml and in dump commands. Signed-off-by: Josh Salomon <jsalomon@redhat.com>
This commit is contained in:
parent
aac5bbd1fe
commit
e9921ee76c
@ -961,7 +961,7 @@ COMMAND("osd force-create-pg "
|
||||
COMMAND("osd pg-temp "
|
||||
"name=pgid,type=CephPgid "
|
||||
"name=id,type=CephOsdName,n=N,req=false",
|
||||
"set pg_temp mapping pgid:[<id> [<id>...]] (developers only)",
|
||||
"set pg_temp mapping <pgid>:[<id> [<id>...]] (developers only)",
|
||||
"osd", "rw")
|
||||
COMMAND("osd pg-upmap "
|
||||
"name=pgid,type=CephPgid "
|
||||
@ -981,6 +981,15 @@ COMMAND("osd rm-pg-upmap-items "
|
||||
"name=pgid,type=CephPgid",
|
||||
"clear pg_upmap_items mapping for <pgid> (developers only)",
|
||||
"osd", "rw")
|
||||
COMMAND("osd pg-upmap-primary "
|
||||
"name=pgid,type=CephPgid "
|
||||
"name=id,type=CephOsdName ",
|
||||
"set pg primary osd <pgid>:<id> (id (osd) must be part of pgid)",
|
||||
"osd", "rw")
|
||||
COMMAND("osd rm-pg-upmap-primary "
|
||||
"name=pgid,type=CephPgid ",
|
||||
"clear pg primary setting for <pgid>",
|
||||
"osd", "rw")
|
||||
COMMAND("osd primary-temp "
|
||||
"name=pgid,type=CephPgid "
|
||||
"name=id,type=CephOsdName",
|
||||
|
@ -5940,19 +5940,10 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
|
||||
|
||||
} else if (prefix == "pg map") {
|
||||
pg_t pgid;
|
||||
string pgidstr;
|
||||
cmd_getval(cmdmap, "pgid", pgidstr);
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
r = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
vector<int> up, acting;
|
||||
if (!osdmap.have_pg_pool(pgid.pool())) {
|
||||
ss << "pg '" << pgidstr << "' does not exist";
|
||||
r = -ENOENT;
|
||||
r = parse_pgid(cmdmap, ss, pgid);
|
||||
if (r < 0)
|
||||
goto reply;
|
||||
}
|
||||
pg_t mpgid = osdmap.raw_pg_to_pg(pgid);
|
||||
osdmap.pg_to_up_acting_osds(pgid, up, acting);
|
||||
if (f) {
|
||||
@ -9892,6 +9883,27 @@ int OSDMonitor::prepare_command_osd_purge(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSDMonitor::parse_pgid(const cmdmap_t& cmdmap, stringstream &ss,
|
||||
/* out */ pg_t &pgid, std::optional<string> pgids) {
|
||||
string pgidstr;
|
||||
if (!cmd_getval(cmdmap, "pgid", pgidstr)) {
|
||||
ss << "unable to parse 'pgid' value '"
|
||||
<< cmd_vartype_stringify(cmdmap.at("pgid")) << "'";
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pgid '" << pgid << "' does not exist";
|
||||
return -ENOENT;
|
||||
}
|
||||
if (pgids.has_value())
|
||||
pgids.value() = pgidstr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
const cmdmap_t& cmdmap)
|
||||
{
|
||||
@ -11966,24 +11978,10 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
return true;
|
||||
}
|
||||
} else if (prefix == "osd pg-temp") {
|
||||
string pgidstr;
|
||||
if (!cmd_getval(cmdmap, "pgid", pgidstr)) {
|
||||
ss << "unable to parse 'pgid' value '"
|
||||
<< cmd_vartype_stringify(cmdmap.at("pgid")) << "'";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
pg_t pgid;
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
err = -EINVAL;
|
||||
err = parse_pgid(cmdmap, ss, pgid);
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pg " << pgid << " does not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
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));
|
||||
@ -12028,24 +12026,10 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
ss << "set " << pgid << " pg_temp mapping to " << new_pg_temp;
|
||||
goto update;
|
||||
} else if (prefix == "osd primary-temp") {
|
||||
string pgidstr;
|
||||
if (!cmd_getval(cmdmap, "pgid", pgidstr)) {
|
||||
ss << "unable to parse 'pgid' value '"
|
||||
<< cmd_vartype_stringify(cmdmap.at("pgid")) << "'";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
pg_t pgid;
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
err = -EINVAL;
|
||||
err = parse_pgid(cmdmap, ss, pgid);
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pg " << pgid << " does not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
|
||||
int64_t osd;
|
||||
if (!cmd_getval(cmdmap, "id", osd)) {
|
||||
@ -12074,18 +12058,9 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
goto update;
|
||||
} else if (prefix == "pg repeer") {
|
||||
pg_t pgid;
|
||||
string pgidstr;
|
||||
cmd_getval(cmdmap, "pgid", pgidstr);
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
err = -EINVAL;
|
||||
err = parse_pgid(cmdmap, ss, pgid);
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pg '" << pgidstr << "' does not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
vector<int> acting;
|
||||
int primary;
|
||||
osdmap.pg_to_acting_osds(pgid, &acting, &primary);
|
||||
@ -12120,39 +12095,77 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
} else if (prefix == "osd pg-upmap" ||
|
||||
prefix == "osd rm-pg-upmap" ||
|
||||
prefix == "osd pg-upmap-items" ||
|
||||
prefix == "osd rm-pg-upmap-items") {
|
||||
if (osdmap.require_min_compat_client < ceph_release_t::luminous) {
|
||||
prefix == "osd rm-pg-upmap-items" ||
|
||||
prefix == "osd pg-upmap-primary" ||
|
||||
prefix == "osd rm-pg-upmap-primary") {
|
||||
enum {
|
||||
OP_PG_UPMAP,
|
||||
OP_RM_PG_UPMAP,
|
||||
OP_PG_UPMAP_ITEMS,
|
||||
OP_RM_PG_UPMAP_ITEMS,
|
||||
OP_PG_UPMAP_PRIMARY,
|
||||
OP_RM_PG_UPMAP_PRIMARY,
|
||||
} upmap_option;
|
||||
|
||||
if (prefix == "osd pg-upmap") {
|
||||
upmap_option = OP_PG_UPMAP;
|
||||
} else if (prefix == "osd rm-pg-upmap") {
|
||||
upmap_option = OP_RM_PG_UPMAP;
|
||||
} else if (prefix == "osd pg-upmap-items") {
|
||||
upmap_option = OP_PG_UPMAP_ITEMS;
|
||||
} else if (prefix == "osd rm-pg-upmap-items") {
|
||||
upmap_option = OP_RM_PG_UPMAP_ITEMS;
|
||||
} else if (prefix == "osd pg-upmap-primary") {
|
||||
upmap_option = OP_PG_UPMAP_PRIMARY;
|
||||
} else if (prefix == "osd rm-pg-upmap-primary") {
|
||||
upmap_option = OP_RM_PG_UPMAP_PRIMARY;
|
||||
} else {
|
||||
ceph_abort_msg("invalid upmap option");
|
||||
}
|
||||
|
||||
ceph_release_t min_release = ceph_release_t::unknown;
|
||||
string feature_name = "unknown";
|
||||
switch (upmap_option) {
|
||||
case OP_PG_UPMAP: // fall through
|
||||
case OP_RM_PG_UPMAP: // fall through
|
||||
case OP_PG_UPMAP_ITEMS: // fall through
|
||||
case OP_RM_PG_UPMAP_ITEMS:
|
||||
min_release = ceph_release_t::luminous;
|
||||
feature_name = "pg-upmap";
|
||||
break;
|
||||
|
||||
case OP_PG_UPMAP_PRIMARY: // fall through
|
||||
case OP_RM_PG_UPMAP_PRIMARY:
|
||||
min_release = ceph_release_t::reef;
|
||||
feature_name = "pg-upmap-primary";
|
||||
break;
|
||||
|
||||
default:
|
||||
ceph_abort_msg("invalid upmap option");
|
||||
}
|
||||
uint64_t min_feature = CEPH_FEATUREMASK_OSDMAP_PG_UPMAP;
|
||||
string min_release_name = ceph_release_name(static_cast<int>(min_release));
|
||||
|
||||
if (osdmap.require_min_compat_client < min_release) {
|
||||
ss << "min_compat_client "
|
||||
<< osdmap.require_min_compat_client
|
||||
<< " < luminous, which is required for pg-upmap. "
|
||||
<< "Try 'ceph osd set-require-min-compat-client luminous' "
|
||||
<< " < " << min_release_name << ", which is required for " << feature_name << ". "
|
||||
<< "Try 'ceph osd set-require-min-compat-client " << min_release_name << "' "
|
||||
<< "before using the new interface";
|
||||
err = -EPERM;
|
||||
goto reply;
|
||||
}
|
||||
err = check_cluster_features(CEPH_FEATUREMASK_OSDMAP_PG_UPMAP, ss);
|
||||
|
||||
//TODO: Should I add feature and test for upmap-primary?
|
||||
err = check_cluster_features(min_feature, ss);
|
||||
if (err == -EAGAIN)
|
||||
goto wait;
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
string pgidstr;
|
||||
if (!cmd_getval(cmdmap, "pgid", pgidstr)) {
|
||||
ss << "unable to parse 'pgid' value '"
|
||||
<< cmd_vartype_stringify(cmdmap.at("pgid")) << "'";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
pg_t pgid;
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
err = -EINVAL;
|
||||
err = parse_pgid(cmdmap, ss, pgid);
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pg " << pgid << " does not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
if (pending_inc.old_pools.count(pgid.pool())) {
|
||||
ss << "pool of " << pgid << " is pending removal";
|
||||
err = -ENOENT;
|
||||
@ -12162,25 +12175,8 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
return true;
|
||||
}
|
||||
|
||||
enum {
|
||||
OP_PG_UPMAP,
|
||||
OP_RM_PG_UPMAP,
|
||||
OP_PG_UPMAP_ITEMS,
|
||||
OP_RM_PG_UPMAP_ITEMS,
|
||||
} option;
|
||||
|
||||
if (prefix == "osd pg-upmap") {
|
||||
option = OP_PG_UPMAP;
|
||||
} else if (prefix == "osd rm-pg-upmap") {
|
||||
option = OP_RM_PG_UPMAP;
|
||||
} else if (prefix == "osd pg-upmap-items") {
|
||||
option = OP_PG_UPMAP_ITEMS;
|
||||
} else {
|
||||
option = OP_RM_PG_UPMAP_ITEMS;
|
||||
}
|
||||
|
||||
// check pending upmap changes
|
||||
switch (option) {
|
||||
switch (upmap_option) {
|
||||
case OP_PG_UPMAP: // fall through
|
||||
case OP_RM_PG_UPMAP:
|
||||
if (pending_inc.new_pg_upmap.count(pgid) ||
|
||||
@ -12192,8 +12188,19 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_PG_UPMAP_ITEMS: // fall through
|
||||
case OP_RM_PG_UPMAP_ITEMS:
|
||||
case OP_PG_UPMAP_PRIMARY: // fall through
|
||||
case OP_RM_PG_UPMAP_PRIMARY:
|
||||
{
|
||||
const pg_pool_t *pt = osdmap.get_pg_pool(pgid.pool());
|
||||
if (! pt->is_replicated()) {
|
||||
ss << "pg-upmap-primary is only supported for replicated pools";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
case OP_PG_UPMAP_ITEMS: // fall through
|
||||
case OP_RM_PG_UPMAP_ITEMS: // fall through
|
||||
if (pending_inc.new_pg_upmap_items.count(pgid) ||
|
||||
pending_inc.old_pg_upmap_items.count(pgid)) {
|
||||
dout(10) << __func__ << " waiting for pending update on "
|
||||
@ -12204,10 +12211,10 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
break;
|
||||
|
||||
default:
|
||||
ceph_abort_msg("invalid option");
|
||||
ceph_abort_msg("invalid upmap option");
|
||||
}
|
||||
|
||||
switch (option) {
|
||||
switch (upmap_option) {
|
||||
case OP_PG_UPMAP:
|
||||
{
|
||||
vector<int64_t> id_vec;
|
||||
@ -12346,8 +12353,69 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_PG_UPMAP_PRIMARY:
|
||||
{
|
||||
int64_t id;
|
||||
if (!cmd_getval(cmdmap, "id", id)) {
|
||||
ss << "invalid osd id value '"
|
||||
<< cmd_vartype_stringify(cmdmap.at("id")) << "'";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
if (id != CRUSH_ITEM_NONE && !osdmap.exists(id)) {
|
||||
ss << "osd." << id << " does not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
vector<int> acting;
|
||||
int primary;
|
||||
osdmap.pg_to_acting_osds(pgid, &acting, &primary);
|
||||
if (id == primary) {
|
||||
ss << "osd." << id << " is already primary for pg " << pgid;
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
int found_idx = 0;
|
||||
for (int i = 1 ; i < (int)acting.size(); i++) { // skip 0 on purpose
|
||||
if (acting[i] == id) {
|
||||
found_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found_idx == 0) {
|
||||
ss << "osd." << id << " is not in acting set for pg " << pgid;
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
vector<int> new_acting(acting);
|
||||
new_acting[found_idx] = new_acting[0];
|
||||
new_acting[0] = id;
|
||||
int pool_size = osdmap.get_pg_pool_size(pgid);
|
||||
if (osdmap.crush->verify_upmap(cct, osdmap.get_pg_pool_crush_rule(pgid),
|
||||
pool_size, new_acting) >= 0) {
|
||||
ss << "change primary for pg " << pgid << " to osd." << id;
|
||||
}
|
||||
else {
|
||||
ss << "can't change primary for pg " << pgid << " to osd." << id
|
||||
<< " - illegal pg after the change";
|
||||
err = -EINVAL;
|
||||
goto reply;
|
||||
}
|
||||
pending_inc.new_pg_upmap_primary[pgid] = id;
|
||||
//TO-REMOVE:
|
||||
ldout(cct, 20) << "pg " << pgid << ": set pg_upmap_primary to " << id << dendl;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_RM_PG_UPMAP_PRIMARY:
|
||||
{
|
||||
pending_inc.old_pg_upmap_primary.insert(pgid);
|
||||
ss << "clear " << pgid << " pg_upmap_primary mapping";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ceph_abort_msg("invalid option");
|
||||
ceph_abort_msg("invalid upmap option");
|
||||
}
|
||||
|
||||
goto update;
|
||||
@ -13748,17 +13816,9 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
|
||||
} else if (prefix == "osd force-create-pg") {
|
||||
pg_t pgid;
|
||||
string pgidstr;
|
||||
cmd_getval(cmdmap, "pgid", pgidstr);
|
||||
if (!pgid.parse(pgidstr.c_str())) {
|
||||
ss << "invalid pgid '" << pgidstr << "'";
|
||||
err = -EINVAL;
|
||||
err = parse_pgid(cmdmap, ss, pgid, pgidstr);
|
||||
if (err < 0)
|
||||
goto reply;
|
||||
}
|
||||
if (!osdmap.pg_exists(pgid)) {
|
||||
ss << "pg " << pgid << " should not exist";
|
||||
err = -ENOENT;
|
||||
goto reply;
|
||||
}
|
||||
bool sure = false;
|
||||
cmd_getval(cmdmap, "yes_i_really_mean_it", sure);
|
||||
if (!sure) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
|
||||
#include "include/types.h"
|
||||
#include "include/encoding.h"
|
||||
@ -674,6 +675,8 @@ protected:
|
||||
bool grace_interval_threshold_exceeded(int last_failed);
|
||||
void set_default_laggy_params(int target_osd);
|
||||
|
||||
int parse_pgid(const cmdmap_t& cmdmap, std::stringstream &ss,
|
||||
pg_t &pgid, std::optional<std::string> pgidstr = std::nullopt);
|
||||
public:
|
||||
OSDMonitor(CephContext *cct, Monitor &mn, Paxos &p, const std::string& service_name);
|
||||
|
||||
|
@ -579,14 +579,16 @@ void OSDMap::Incremental::encode(ceph::buffer::list& bl, uint64_t features) cons
|
||||
ENCODE_START(8, 7, bl);
|
||||
|
||||
{
|
||||
uint8_t v = 8;
|
||||
uint8_t v = 9;
|
||||
if (!HAVE_FEATURE(features, SERVER_LUMINOUS)) {
|
||||
v = 3;
|
||||
} else if (!HAVE_FEATURE(features, SERVER_MIMIC)) {
|
||||
v = 5;
|
||||
} else if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
|
||||
v = 6;
|
||||
}
|
||||
} /* else if (!HAVE_FEATURE(features, SERVER_REEF)) {
|
||||
v = 8;
|
||||
} */
|
||||
ENCODE_START(v, 1, bl); // client-usable data
|
||||
encode(fsid, bl);
|
||||
encode(epoch, bl);
|
||||
@ -645,6 +647,10 @@ void OSDMap::Incremental::encode(ceph::buffer::list& bl, uint64_t features) cons
|
||||
encode(new_last_up_change, bl);
|
||||
encode(new_last_in_change, bl);
|
||||
}
|
||||
if (v >= 9) {
|
||||
encode(new_pg_upmap_primary, bl);
|
||||
encode(old_pg_upmap_primary, bl);
|
||||
}
|
||||
ENCODE_FINISH(bl); // client-usable data
|
||||
}
|
||||
|
||||
@ -1196,6 +1202,23 @@ void OSDMap::Incremental::dump(Formatter *f) const
|
||||
}
|
||||
f->close_section();
|
||||
|
||||
// dump upmap_primaries
|
||||
f->open_array_section("new_pg_upmap_primaries");
|
||||
for (auto& [pg, osd] : new_pg_upmap_primary) {
|
||||
f->open_object_section("primary_mapping");
|
||||
f->dump_stream("pgid") << pg;
|
||||
f->dump_int("primary_osd", osd);
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section(); // new_pg_upmap_primaries
|
||||
|
||||
// dump old_pg_upmap_primaries (removed primary mappings)
|
||||
f->open_array_section("old_pg_upmap_primaries");
|
||||
for (auto& pg : old_pg_upmap_primary) {
|
||||
f->dump_stream("pgid") << pg;
|
||||
}
|
||||
f->close_section(); // old_pg_upmap_primaries
|
||||
|
||||
f->open_array_section("new_up_thru");
|
||||
|
||||
for (const auto &up_thru : new_up_thru) {
|
||||
@ -1709,7 +1732,7 @@ uint64_t OSDMap::get_features(int entity_type, uint64_t *pmask) const
|
||||
}
|
||||
mask |= CEPH_FEATURES_CRUSH;
|
||||
|
||||
if (!pg_upmap.empty() || !pg_upmap_items.empty())
|
||||
if (!pg_upmap.empty() || !pg_upmap_items.empty() || !pg_upmap_primaries.empty())
|
||||
features |= CEPH_FEATUREMASK_OSDMAP_PG_UPMAP;
|
||||
mask |= CEPH_FEATUREMASK_OSDMAP_PG_UPMAP;
|
||||
|
||||
@ -2074,13 +2097,13 @@ bool OSDMap::check_pg_upmaps(
|
||||
auto i = pg_upmap.find(pg);
|
||||
if (i != pg_upmap.end()) {
|
||||
if (i->second == raw) {
|
||||
ldout(cct, 10) << "removing redundant pg_upmap " << i->first << " "
|
||||
ldout(cct, 10) << __func__ << "removing redundant pg_upmap " << i->first << " "
|
||||
<< i->second << dendl;
|
||||
to_cancel->push_back(pg);
|
||||
continue;
|
||||
}
|
||||
if ((int)i->second.size() != get_pg_pool_size(pg)) {
|
||||
ldout(cct, 10) << "removing pg_upmap " << i->first << " "
|
||||
ldout(cct, 10) << __func__ << "removing pg_upmap " << i->first << " "
|
||||
<< i->second << " != pool size " << get_pg_pool_size(pg)
|
||||
<< dendl;
|
||||
to_cancel->push_back(pg);
|
||||
@ -2091,24 +2114,29 @@ bool OSDMap::check_pg_upmaps(
|
||||
if (j != pg_upmap_items.end()) {
|
||||
mempool::osdmap::vector<pair<int,int>> newmap;
|
||||
for (auto& p : j->second) {
|
||||
if (std::find(raw.begin(), raw.end(), p.first) == raw.end()) {
|
||||
auto osd_from = p.first;
|
||||
auto osd_to = p.second;
|
||||
if (std::find(raw.begin(), raw.end(), osd_from) == raw.end()) {
|
||||
// cancel mapping if source osd does not exist anymore
|
||||
ldout(cct, 20) << __func__ << " pg_upmap_items (source osd does not exist) " << pg_upmap_items << dendl;
|
||||
continue;
|
||||
}
|
||||
if (p.second != CRUSH_ITEM_NONE && p.second < max_osd &&
|
||||
p.second >= 0 && osd_weight[p.second] == 0) {
|
||||
if (osd_to != CRUSH_ITEM_NONE && osd_to < max_osd &&
|
||||
osd_to >= 0 && osd_weight[osd_to] == 0) {
|
||||
// cancel mapping if target osd is out
|
||||
ldout(cct, 20) << __func__ << " pg_upmap_items (target osd is out) " << pg_upmap_items << dendl;
|
||||
continue;
|
||||
}
|
||||
newmap.push_back(p);
|
||||
}
|
||||
if (newmap.empty()) {
|
||||
ldout(cct, 10) << " removing no-op pg_upmap_items "
|
||||
ldout(cct, 10) << __func__ << " removing no-op pg_upmap_items "
|
||||
<< j->first << " " << j->second
|
||||
<< dendl;
|
||||
to_cancel->push_back(pg);
|
||||
} else if (newmap != j->second) {
|
||||
ldout(cct, 10) << " simplifying partially no-op pg_upmap_items "
|
||||
} else {
|
||||
//Josh--check partial no-op here.
|
||||
ldout(cct, 10) << __func__ << " simplifying partially no-op pg_upmap_items "
|
||||
<< j->first << " " << j->second
|
||||
<< " -> " << newmap
|
||||
<< dendl;
|
||||
@ -2176,6 +2204,9 @@ bool OSDMap::clean_pg_upmaps(
|
||||
get_upmap_pgs(&to_check);
|
||||
auto any_change = check_pg_upmaps(cct, to_check, &to_cancel, &to_remap);
|
||||
clean_pg_upmaps(cct, pending_inc, to_cancel, to_remap);
|
||||
//TODO: Create these 3 functions for pg_upmap_primaries and so they can be checked
|
||||
// and cleaned in the same way as pg_upmap. This is not critical since invalid
|
||||
// pg_upmap_primaries are never applied, (the final check is in _apply_upmap).
|
||||
return any_change;
|
||||
}
|
||||
|
||||
@ -2388,6 +2419,13 @@ int OSDMap::apply_incremental(const Incremental &inc)
|
||||
pg_upmap_items.erase(pg);
|
||||
}
|
||||
|
||||
for (auto& [pg, prim] : inc.new_pg_upmap_primary) {
|
||||
pg_upmap_primaries[pg] = prim;
|
||||
}
|
||||
for (auto& pg : inc.old_pg_upmap_primary) {
|
||||
pg_upmap_primaries.erase(pg);
|
||||
}
|
||||
|
||||
// blocklist
|
||||
if (!inc.new_blocklist.empty()) {
|
||||
blocklist.insert(inc.new_blocklist.begin(),inc.new_blocklist.end());
|
||||
@ -2614,26 +2652,47 @@ void OSDMap::_apply_upmap(const pg_pool_t& pi, pg_t raw_pg, vector<int> *raw) co
|
||||
if (q != pg_upmap_items.end()) {
|
||||
// NOTE: this approach does not allow a bidirectional swap,
|
||||
// e.g., [[1,2],[2,1]] applied to [0,1,2] -> [0,2,1].
|
||||
for (auto& r : q->second) {
|
||||
for (auto& [osd_from, osd_to] : q->second) {
|
||||
// A capcaity change upmap (repace osd in the pg with osd not in the pg)
|
||||
// make sure the replacement value doesn't already appear
|
||||
bool exists = false;
|
||||
ssize_t pos = -1;
|
||||
for (unsigned i = 0; i < raw->size(); ++i) {
|
||||
int osd = (*raw)[i];
|
||||
if (osd == r.second) {
|
||||
if (osd == osd_to) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
// ignore mapping if target is marked out (or invalid osd id)
|
||||
if (osd == r.first &&
|
||||
if (osd == osd_from &&
|
||||
pos < 0 &&
|
||||
!(r.second != CRUSH_ITEM_NONE && r.second < max_osd &&
|
||||
r.second >= 0 && osd_weight[r.second] == 0)) {
|
||||
!(osd_to != CRUSH_ITEM_NONE && osd_to < max_osd &&
|
||||
osd_to >= 0 && osd_weight[osd_to] == 0)) {
|
||||
pos = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exists && pos >= 0) {
|
||||
(*raw)[pos] = r.second;
|
||||
(*raw)[pos] = osd_to;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto r = pg_upmap_primaries.find(pg);
|
||||
if (r != pg_upmap_primaries.end()) {
|
||||
auto new_prim = r->second;
|
||||
// Apply mapping only if new primary is not marked out and valid osd id
|
||||
if (new_prim != CRUSH_ITEM_NONE && new_prim < max_osd && new_prim >= 0 &&
|
||||
osd_weight[new_prim] != 0) {
|
||||
int new_prim_idx = 0;
|
||||
for (int i = 1 ; i < (int)raw->size(); i++) { // start from 1 on purpose
|
||||
if ((*raw)[i] == new_prim) {
|
||||
new_prim_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_prim_idx > 0) {
|
||||
// swap primary
|
||||
(*raw)[new_prim_idx] = (*raw)[0];
|
||||
(*raw)[0] = new_prim;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3068,14 +3127,16 @@ void OSDMap::encode(ceph::buffer::list& bl, uint64_t features) const
|
||||
{
|
||||
// NOTE: any new encoding dependencies must be reflected by
|
||||
// SIGNIFICANT_FEATURES
|
||||
uint8_t v = 9;
|
||||
uint8_t v = 10;
|
||||
if (!HAVE_FEATURE(features, SERVER_LUMINOUS)) {
|
||||
v = 3;
|
||||
} else if (!HAVE_FEATURE(features, SERVER_MIMIC)) {
|
||||
v = 6;
|
||||
} else if (!HAVE_FEATURE(features, SERVER_NAUTILUS)) {
|
||||
v = 7;
|
||||
}
|
||||
} /* else if (!HAVE_FEATURE(features, SERVER_REEF)) {
|
||||
v = 9;
|
||||
} */
|
||||
ENCODE_START(v, 1, bl); // client-usable data
|
||||
// base
|
||||
encode(fsid, bl);
|
||||
@ -3150,6 +3211,11 @@ void OSDMap::encode(ceph::buffer::list& bl, uint64_t features) const
|
||||
encode(last_up_change, bl);
|
||||
encode(last_in_change, bl);
|
||||
}
|
||||
if (v >= 10) {
|
||||
encode(pg_upmap_primaries, bl);
|
||||
} else {
|
||||
ceph_assert(pg_upmap_primaries.empty());
|
||||
}
|
||||
ENCODE_FINISH(bl); // client-usable data
|
||||
}
|
||||
|
||||
@ -3484,6 +3550,11 @@ void OSDMap::decode(ceph::buffer::list::const_iterator& bl)
|
||||
decode(last_up_change, bl);
|
||||
decode(last_in_change, bl);
|
||||
}
|
||||
if (struct_v >= 10) {
|
||||
decode(pg_upmap_primaries, bl);
|
||||
} else {
|
||||
pg_upmap_primaries.clear();
|
||||
}
|
||||
DECODE_FINISH(bl); // client-usable data
|
||||
}
|
||||
|
||||
@ -3753,21 +3824,32 @@ void OSDMap::dump(Formatter *f) const
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section();
|
||||
|
||||
f->open_array_section("pg_upmap_items");
|
||||
for (auto& p : pg_upmap_items) {
|
||||
for (auto& [pgid, mappings] : pg_upmap_items) {
|
||||
f->open_object_section("mapping");
|
||||
f->dump_stream("pgid") << p.first;
|
||||
f->dump_stream("pgid") << pgid;
|
||||
f->open_array_section("mappings");
|
||||
for (auto& q : p.second) {
|
||||
for (auto& [from, to] : mappings) {
|
||||
f->open_object_section("mapping");
|
||||
f->dump_int("from", q.first);
|
||||
f->dump_int("to", q.second);
|
||||
f->dump_int("from", from);
|
||||
f->dump_int("to", to);
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section();
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section();
|
||||
|
||||
f->open_array_section("pg_upmap_primaries");
|
||||
for (const auto& [pg, osd] : pg_upmap_primaries) {
|
||||
f->open_object_section("primary_mapping");
|
||||
f->dump_stream("pgid") << pg;
|
||||
f->dump_int("primary_osd", osd);
|
||||
f->close_section();
|
||||
}
|
||||
f->close_section(); // primary_temp
|
||||
|
||||
f->open_array_section("pg_temp");
|
||||
pg_temp->dump(f);
|
||||
f->close_section();
|
||||
@ -4049,6 +4131,10 @@ void OSDMap::print(ostream& out) const
|
||||
out << "pg_upmap_items " << p.first << " " << p.second << "\n";
|
||||
}
|
||||
|
||||
for (auto& [pg, osd] : pg_upmap_primaries) {
|
||||
out << "pg_upmap_primary " << pg << " " << osd << "\n";
|
||||
}
|
||||
|
||||
for (const auto& pg : *pg_temp)
|
||||
out << "pg_temp " << pg.first << " " << pg.second << "\n";
|
||||
|
||||
|
@ -404,7 +404,8 @@ public:
|
||||
|
||||
mempool::osdmap::map<pg_t,mempool::osdmap::vector<int32_t>> new_pg_upmap;
|
||||
mempool::osdmap::map<pg_t,mempool::osdmap::vector<std::pair<int32_t,int32_t>>> new_pg_upmap_items;
|
||||
mempool::osdmap::set<pg_t> old_pg_upmap, old_pg_upmap_items;
|
||||
mempool::osdmap::map<pg_t, int32_t> new_pg_upmap_primary;
|
||||
mempool::osdmap::set<pg_t> old_pg_upmap, old_pg_upmap_items, old_pg_upmap_primary;
|
||||
mempool::osdmap::map<int64_t, snap_interval_set_t> new_removed_snaps;
|
||||
mempool::osdmap::map<int64_t, snap_interval_set_t> new_purged_snaps;
|
||||
|
||||
@ -575,6 +576,7 @@ private:
|
||||
// remap (post-CRUSH, pre-up)
|
||||
mempool::osdmap::map<pg_t,mempool::osdmap::vector<int32_t>> pg_upmap; ///< remap pg
|
||||
mempool::osdmap::map<pg_t,mempool::osdmap::vector<std::pair<int32_t,int32_t>>> pg_upmap_items; ///< remap osds in up set
|
||||
mempool::osdmap::map<pg_t, int32_t> pg_upmap_primaries; ///< remap primary of a pg
|
||||
|
||||
mempool::osdmap::map<int64_t,pg_pool_t> pools;
|
||||
mempool::osdmap::map<int64_t,std::string> pool_name;
|
||||
|
@ -1333,6 +1333,7 @@ if [ "$debug" -eq 0 ]; then
|
||||
else
|
||||
debug echo "** going verbose **"
|
||||
CMONDEBUG='
|
||||
debug osd = 20
|
||||
debug mon = 20
|
||||
debug paxos = 20
|
||||
debug auth = 20
|
||||
|
Loading…
Reference in New Issue
Block a user