ack_stamp = ceph_clock_now();
MMonElection *m = new MMonElection(MMonElection::OP_ACK, epoch, mon->monmap);
m->mon_features = ceph::features::mon::get_supported();
- m->sharing_bl = mon->get_supported_commands_bl();
+ m->sharing_bl = mon->get_local_commands_bl();
mon->collect_metadata(&m->metadata);
mon->messenger->send_message(m, mon->monmap->get_inst(who));
assert(epoch % 2 == 1); // election
bump_epoch(epoch+1); // is over!
- // decide my supported commands for peons to advertise
- const bufferlist *cmds_bl = NULL;
- const MonCommand *cmds;
- int cmdsize;
- mon->get_locally_supported_monitor_commands(&cmds, &cmdsize);
- cmds_bl = &mon->get_supported_commands_bl();
-
// tell everyone!
for (set<int>::iterator p = quorum.begin();
p != quorum.end();
++p) {
if (*p == mon->rank) continue;
- MMonElection *m = new MMonElection(MMonElection::OP_VICTORY, epoch, mon->monmap);
+ MMonElection *m = new MMonElection(MMonElection::OP_VICTORY, epoch,
+ mon->monmap);
m->quorum = quorum;
m->quorum_features = cluster_features;
m->mon_features = mon_features;
- m->sharing_bl = *cmds_bl;
+ m->sharing_bl = mon->get_local_commands_bl();
mon->messenger->send_message(m, mon->monmap->get_inst(*p));
}
// tell monitor
mon->win_election(epoch, quorum,
- cluster_features, mon_features, metadata,
- cmds, cmdsize);
+ cluster_features, mon_features, metadata);
}
// stash leader's commands
assert(m->sharing_bl.length());
- MonCommand *new_cmds;
- int cmdsize;
+ vector<MonCommand> new_cmds;
bufferlist::iterator bi = m->sharing_bl.begin();
- MonCommand::decode_array(&new_cmds, &cmdsize, bi);
- mon->set_leader_supported_commands(new_cmds, cmdsize);
+ MonCommand::decode_vector(new_cmds, bi);
+ mon->set_leader_commands(new_cmds);
}
void Elector::nak_old_peer(MonOpRequestRef op)
DECODE_FINISH(bl);
}
+ // this uses a u16 for the count, so we need a special encoder/decoder.
+ static void encode_vector(const std::vector<MonCommand>& cmds,
+ bufferlist &bl) {
+ ENCODE_START(2, 1, bl);
+ uint16_t s = cmds.size();
+ ::encode(s, bl);
+ for (unsigned i = 0; i < s; ++i) {
+ cmds[i].encode_bare(bl);
+ }
+ for (unsigned i = 0; i < s; i++) {
+ ::encode(cmds[i].flags, bl);
+ }
+ ENCODE_FINISH(bl);
+ }
+ static void decode_vector(std::vector<MonCommand> &cmds,
+ bufferlist::iterator &bl) {
+ DECODE_START(2, bl);
+ uint16_t s = 0;
+ ::decode(s, bl);
+ cmds.resize(s);
+ for (unsigned i = 0; i < s; ++i) {
+ cmds[i].decode_bare(bl);
+ }
+ if (struct_v >= 2) {
+ for (unsigned i = 0; i < s; i++)
+ ::decode(cmds[i].flags, bl);
+ } else {
+ for (unsigned i = 0; i < s; i++)
+ cmds[i].flags = 0;
+ }
+ DECODE_FINISH(bl);
+ }
+
bool requires_perm(char p) const {
return (req_perms.find(p) != std::string::npos);
}
auth_service_required(cct,
cct->_conf->auth_supported.empty() ?
cct->_conf->auth_service_required : cct->_conf->auth_supported ),
- leader_supported_mon_commands(NULL),
- leader_supported_mon_commands_size(0),
mgr_messenger(mgr_m),
mgr_client(cct_, mgr_m),
pgservice(nullptr),
exited_quorum = ceph_clock_now();
+ // prepare local commands
+ local_mon_commands.resize(ARRAY_SIZE(mon_commands));
+ for (unsigned i = 0; i < ARRAY_SIZE(mon_commands); ++i) {
+ local_mon_commands[i] = mon_commands[i];
+ }
+ MonCommand::encode_vector(local_mon_commands, local_mon_commands_bl);
+
// assume our commands until we have an election. this only means
// we won't reply with EINVAL before the election; any command that
// actually matters will wait until we have quorum etc and then
// retry (and revalidate).
- const MonCommand *cmds;
- int cmdsize;
- get_locally_supported_monitor_commands(&cmds, &cmdsize);
- set_leader_supported_commands(cmds, cmdsize);
+ leader_mon_commands = local_mon_commands;
// note: OSDMonitor may update this based on the luminous flag.
pgservice = mgrstatmon()->get_pg_stat_service();
delete paxos;
assert(session_map.sessions.empty());
delete mon_caps;
- if (leader_supported_mon_commands != mon_commands)
- delete[] leader_supported_mon_commands;
}
mgr_messenger->add_dispatcher_tail(this); // for auth ms_* calls
bootstrap();
-
- // encode command sets
- const MonCommand *cmds;
- int cmdsize;
- get_locally_supported_monitor_commands(&cmds, &cmdsize);
- MonCommand::encode_array(cmds, cmdsize, supported_commands_bl);
-
return 0;
}
map<int,Metadata> metadata;
collect_metadata(&metadata[0]);
- const MonCommand *my_cmds = nullptr;
- int cmdsize = 0;
- get_locally_supported_monitor_commands(&my_cmds, &cmdsize);
win_election(elector.get_epoch(), q,
CEPH_FEATURES_ALL,
ceph::features::mon::get_supported(),
- metadata,
- my_cmds, cmdsize);
+ metadata);
}
const utime_t& Monitor::get_leader_since() const
void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features,
const mon_feature_t& mon_features,
- const map<int,Metadata>& metadata,
- const MonCommand *cmdset, int cmdsize)
+ const map<int,Metadata>& metadata)
{
dout(10) << __func__ << " epoch " << epoch << " quorum " << active
<< " features " << features
clog->info() << "mon." << name << "@" << rank
<< " won leader election with quorum " << quorum;
- set_leader_supported_commands(cmdset, cmdsize);
+ set_leader_commands(get_local_commands());
paxos->leader_init();
// NOTE: tell monmap monitor first. This is important for the
const MonCommand *Monitor::_get_moncommand(
const string &cmd_prefix,
- const MonCommand *cmds,
- int cmds_size)
-{
- const MonCommand *this_cmd = NULL;
- for (const MonCommand *cp = cmds;
- cp < &cmds[cmds_size]; cp++) {
- if (cp->cmdstring.compare(0, cmd_prefix.size(), cmd_prefix) == 0) {
- this_cmd = cp;
- break;
+ const vector<MonCommand>& cmds)
+{
+ for (auto& c : cmds) {
+ if (c.cmdstring.compare(0, cmd_prefix.size(), cmd_prefix) == 0) {
+ return &c;
}
}
- return this_cmd;
+ return nullptr;
}
bool Monitor::_allowed_command(MonSession *s, string &module, string &prefix,
f->flush(*rdata);
}
-void Monitor::get_locally_supported_monitor_commands(const MonCommand **cmds,
- int *count)
-{
- *cmds = mon_commands;
- *count = ARRAY_SIZE(mon_commands);
-}
-void Monitor::set_leader_supported_commands(const MonCommand *cmds, int size)
-{
- if (leader_supported_mon_commands != mon_commands)
- delete[] leader_supported_mon_commands;
- leader_supported_mon_commands = cmds;
- leader_supported_mon_commands_size = size;
-}
-
bool Monitor::is_keyring_required()
{
string auth_cluster_required = g_conf->auth_supported.empty() ?
commands = static_cast<MgrMonitor*>(
paxos_service[PAXOS_MGR])->get_command_descs();
- for (int i = 0 ; i < leader_supported_mon_commands_size; ++i) {
- commands.push_back(leader_supported_mon_commands[i]);
+ for (auto& c : leader_mon_commands) {
+ commands.push_back(c);
}
format_command_descriptions(commands, f, &rdata, hide_mgr_flag);
const auto& mgr_cmds = mgrmon()->get_command_descs();
const MonCommand *mgr_cmd = nullptr;
if (!mgr_cmds.empty()) {
- mgr_cmd = _get_moncommand(prefix, &mgr_cmds.at(0), mgr_cmds.size());
+ mgr_cmd = _get_moncommand(prefix, mgr_cmds);
}
- leader_cmd = _get_moncommand(prefix,
- // the boost underlying this isn't const for some reason
- const_cast<MonCommand*>(leader_supported_mon_commands),
- leader_supported_mon_commands_size);
+ leader_cmd = _get_moncommand(prefix, leader_mon_commands);
if (!leader_cmd) {
leader_cmd = mgr_cmd;
if (!leader_cmd) {
}
}
// validate command is in our map & matches, or forward if it is allowed
- const MonCommand *mon_cmd = _get_moncommand(prefix, mon_commands,
- ARRAY_SIZE(mon_commands));
+ const MonCommand *mon_cmd = _get_moncommand(prefix, get_local_commands());
if (!mon_cmd) {
mon_cmd = mgr_cmd;
}
CompatSet features;
- const MonCommand *leader_supported_mon_commands;
- int leader_supported_mon_commands_size;
+ vector<MonCommand> leader_mon_commands; // quorum leader's commands
+ vector<MonCommand> local_mon_commands; // commands i support
+ bufferlist local_mon_commands_bl; // encoded version of above
Messenger *mgr_messenger;
MgrClient mgr_client;
* Intersection of quorum members mon-specific feature bits
*/
mon_feature_t quorum_mon_features;
- bufferlist supported_commands_bl; // encoded MonCommands we support
set<string> outside_quorum;
void win_election(epoch_t epoch, set<int>& q,
uint64_t features,
const mon_feature_t& mon_features,
- const map<int,Metadata>& metadata,
- const MonCommand *cmdset, int cmdsize);
+ const map<int,Metadata>& metadata);
void lose_election(epoch_t epoch, set<int>& q, int l,
uint64_t features,
const mon_feature_t& mon_features);
// end election (called by Elector)
void finish_election();
- const bufferlist& get_supported_commands_bl() {
- return supported_commands_bl;
- }
-
void update_logger();
/**
map<string,string> ¶m_str_map);
static const MonCommand *_get_moncommand(
const string &cmd_prefix,
- const MonCommand *cmds,
- int cmds_size);
+ const vector<MonCommand>& cmds);
bool _allowed_command(MonSession *s, string &module, string &prefix,
const map<string,cmd_vartype>& cmdmap,
const map<string,string>& param_str_map,
Formatter *f,
bufferlist *rdata,
bool hide_mgr_flag=false);
- void get_locally_supported_monitor_commands(const MonCommand **cmds, int *count);
- /// the Monitor owns this pointer once you pass it in
- void set_leader_supported_commands(const MonCommand *cmds, int size);
+
+ const std::vector<MonCommand> &get_local_commands() {
+ return local_mon_commands;
+ }
+ const bufferlist& get_local_commands_bl() {
+ return local_mon_commands_bl;
+ }
+ void set_leader_commands(const std::vector<MonCommand>& cmds) {
+ leader_mon_commands = cmds;
+ }
+
static bool is_keyring_required();
};