From 349b3c9bef12728c336cf584ea5c70b8184b66e9 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 5 Aug 2017 15:08:26 -0400 Subject: [PATCH] mon: use vector throughput for commands The old code was pretty messy. This is standardizes on std::vector throughout. We also drop the win_election command args because when we win an election we always set the leader commands to our commands, and we can do that inside win_command() without passing them in from here. Signed-off-by: Sage Weil --- src/mon/Elector.cc | 24 +++++--------- src/mon/MonCommand.h | 33 +++++++++++++++++++ src/mon/Monitor.cc | 78 +++++++++++++------------------------------- src/mon/Monitor.h | 30 +++++++++-------- 4 files changed, 79 insertions(+), 86 deletions(-) diff --git a/src/mon/Elector.cc b/src/mon/Elector.cc index a2244a3c6da04..a0cc7272574c6 100644 --- a/src/mon/Elector.cc +++ b/src/mon/Elector.cc @@ -117,7 +117,7 @@ void Elector::defer(int who) 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)); @@ -201,30 +201,23 @@ void Elector::victory() 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::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); } @@ -394,11 +387,10 @@ void Elector::handle_victory(MonOpRequestRef op) // stash leader's commands assert(m->sharing_bl.length()); - MonCommand *new_cmds; - int cmdsize; + vector 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) diff --git a/src/mon/MonCommand.h b/src/mon/MonCommand.h index e32cc5df2be24..ce2429fbc949c 100644 --- a/src/mon/MonCommand.h +++ b/src/mon/MonCommand.h @@ -120,6 +120,39 @@ struct MonCommand { DECODE_FINISH(bl); } + // this uses a u16 for the count, so we need a special encoder/decoder. + static void encode_vector(const std::vector& 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 &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); } diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 23d0c96fa159f..41adf5c960300 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -143,8 +143,6 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s, 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), @@ -205,14 +203,18 @@ Monitor::Monitor(CephContext* cct_, string nm, MonitorDBStore *s, 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(); @@ -227,8 +229,6 @@ Monitor::~Monitor() delete paxos; assert(session_map.sessions.empty()); delete mon_caps; - if (leader_supported_mon_commands != mon_commands) - delete[] leader_supported_mon_commands; } @@ -786,13 +786,6 @@ int Monitor::init() 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; } @@ -1861,14 +1854,10 @@ void Monitor::win_standalone_election() map 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 @@ -1896,8 +1885,7 @@ void Monitor::_finish_svc_election() void Monitor::win_election(epoch_t epoch, set& active, uint64_t features, const mon_feature_t& mon_features, - const map& metadata, - const MonCommand *cmdset, int cmdsize) + const map& metadata) { dout(10) << __func__ << " epoch " << epoch << " quorum " << active << " features " << features @@ -1916,7 +1904,7 @@ void Monitor::win_election(epoch_t epoch, set& active, uint64_t 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 @@ -2812,18 +2800,14 @@ void Monitor::_generate_command_map(map& cmdmap, 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& 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, @@ -2870,20 +2854,6 @@ void Monitor::format_command_descriptions(const std::vector &command 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() ? @@ -2978,8 +2948,8 @@ void Monitor::handle_command(MonOpRequestRef op) commands = static_cast( 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); @@ -3015,12 +2985,9 @@ void Monitor::handle_command(MonOpRequestRef op) 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(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) { @@ -3029,8 +2996,7 @@ void Monitor::handle_command(MonOpRequestRef op) } } // 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; } diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 2716f0cb5d0dc..283f560a2f693 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -165,8 +165,9 @@ public: CompatSet features; - const MonCommand *leader_supported_mon_commands; - int leader_supported_mon_commands_size; + vector leader_mon_commands; // quorum leader's commands + vector local_mon_commands; // commands i support + bufferlist local_mon_commands_bl; // encoded version of above Messenger *mgr_messenger; MgrClient mgr_client; @@ -248,7 +249,6 @@ private: * Intersection of quorum members mon-specific feature bits */ mon_feature_t quorum_mon_features; - bufferlist supported_commands_bl; // encoded MonCommands we support set outside_quorum; @@ -600,18 +600,13 @@ public: void win_election(epoch_t epoch, set& q, uint64_t features, const mon_feature_t& mon_features, - const map& metadata, - const MonCommand *cmdset, int cmdsize); + const map& metadata); void lose_election(epoch_t epoch, set& 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(); /** @@ -687,8 +682,7 @@ public: map ¶m_str_map); static const MonCommand *_get_moncommand( const string &cmd_prefix, - const MonCommand *cmds, - int cmds_size); + const vector& cmds); bool _allowed_command(MonSession *s, string &module, string &prefix, const map& cmdmap, const map& param_str_map, @@ -967,9 +961,17 @@ public: 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 &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& cmds) { + leader_mon_commands = cmds; + } + static bool is_keyring_required(); }; -- 2.39.5