Monitor: Elector: share the classic command set if we have a classic mon

The leader now checks to see if any monitors did not provide their
command set, and if so, shares the list of "classic" commands instead
of his own set. This will prevent users from seeing different commands
(depending on whether they connect to an old or new mon) while
performing upgrades, and will make it really obvious if they forgot
to upgrade one of the monitors!

Signed-off-by: Greg Farnum <greg@inktank.com>
This commit is contained in:
Greg Farnum 2013-12-09 08:44:05 -08:00
parent f1ccdb418b
commit ea86444fb3
4 changed files with 40 additions and 14 deletions

View File

@ -170,7 +170,18 @@ void Elector::victory()
++p) {
quorum.insert(p->first);
features &= p->second;
}
}
// decide what command set we're supporting
bool use_classic_commands = false;
for (list<bufferlist>::iterator i = acker_commands.begin();
i != acker_commands.end();
++i) {
if (i->length() == 0) {
use_classic_commands = true;
break;
}
}
cancel_timer();
@ -178,11 +189,21 @@ void Elector::victory()
bump_epoch(epoch+1); // is over!
// calculate my supported commands for peons to advertise
if (!my_supported_commands.length()) {
const MonCommand *cmds;
int cmdsize;
bufferlist *cmds_bl = NULL;
const MonCommand *cmds;
int cmdsize;
if (!use_classic_commands) {
get_locally_supported_monitor_commands(&cmds, &cmdsize);
MonCommand::encode_array(cmds, cmdsize, my_supported_commands);
if(!my_supported_commands.length()) {
MonCommand::encode_array(cmds, cmdsize, my_supported_commands);
}
cmds_bl = &my_supported_commands;
} else {
get_classic_monitor_commands(&cmds, &cmdsize);
if (!classic_commands.length()){
MonCommand::encode_array(cmds, cmdsize, classic_commands);
}
cmds_bl = &classic_commands;
}
// tell everyone!
@ -193,12 +214,12 @@ void Elector::victory()
MMonElection *m = new MMonElection(MMonElection::OP_VICTORY, epoch, mon->monmap);
m->quorum = quorum;
m->quorum_features = features;
m->commands = my_supported_commands;
m->commands = *cmds_bl;
mon->messenger->send_message(m, mon->monmap->get_inst(*p));
}
// tell monitor
mon->win_election(epoch, quorum, features);
mon->win_election(epoch, quorum, features, cmds, cmdsize);
}

View File

@ -116,6 +116,7 @@ class Elector {
map<int, uint64_t> acked_me;
list<bufferlist> acker_commands;
bufferlist my_supported_commands;
bufferlist classic_commands;
/**
* @}
*/

View File

@ -1489,7 +1489,11 @@ void Monitor::win_standalone_election()
assert(rank == 0);
set<int> q;
q.insert(rank);
win_election(1, q, CEPH_FEATURES_ALL);
const MonCommand *my_cmds;
int cmdsize;
get_locally_supported_monitor_commands(&my_cmds, &cmdsize);
win_election(1, q, CEPH_FEATURES_ALL, my_cmds, cmdsize);
}
const utime_t& Monitor::get_leader_since() const
@ -1503,7 +1507,8 @@ epoch_t Monitor::get_epoch()
return elector.get_epoch();
}
void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features)
void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features,
const MonCommand *cmdset, int cmdsize)
{
dout(10) << __func__ << " epoch " << epoch << " quorum " << active
<< " features " << features << dendl;
@ -1518,10 +1523,7 @@ void Monitor::win_election(epoch_t epoch, set<int>& active, uint64_t features)
clog.info() << "mon." << name << "@" << rank
<< " won leader election with quorum " << quorum << "\n";
const MonCommand *new_cmds;
int cmdsize;
get_locally_supported_monitor_commands(&new_cmds, &cmdsize);
set_leader_supported_commands(new_cmds, cmdsize);
set_leader_supported_commands(cmdset, cmdsize);
paxos->leader_init();
for (vector<PaxosService*>::iterator p = paxos_service.begin(); p != paxos_service.end(); ++p)

View File

@ -527,8 +527,10 @@ public:
void join_election();
void start_election();
void win_standalone_election();
// end election (called by Elector)
void win_election(epoch_t epoch, set<int>& q,
uint64_t features); // end election (called by Elector)
uint64_t features,
const MonCommand *cmdset, int cmdsize);
void lose_election(epoch_t epoch, set<int>& q, int l,
uint64_t features); // end election (called by Elector)
void finish_election();