global_init(NULL, args, CEPH_ENTITY_TYPE_MDS, CODE_ENVIRONMENT_DAEMON, 0);
// mds specific args
- int shadow = 0;
+ MDSMap::DaemonState shadow = MDSMap::STATE_NULL;
std::string dump_file;
std::string val, action;
}
else if (ceph_argparse_witharg(args, i, &val, "--journal-check", (char*)NULL)) {
int r = parse_rank("journal-check", val);
- if (shadow) {
+ if (shadow != MDSMap::STATE_NULL) {
dout(0) << "Error: can only select one standby state" << dendl;
return -1;
}
name(n),
whoami(-1), incarnation(0),
standby_for_rank(MDSMap::MDS_NO_STANDBY_PREF),
- standby_type(0),
+ standby_type(MDSMap::STATE_NULL),
standby_replaying(false),
messenger(m),
monc(mc),
}
}
-int MDS::init(int wanted_state)
+int MDS::init(MDSMap::DaemonState wanted_state)
{
dout(10) << sizeof(MDSCacheObject) << "\tMDSCacheObject" << dendl;
dout(10) << sizeof(CInode) << "\tCInode" << dendl;
}
mds_lock.Lock();
- if (want_state == CEPH_MDS_STATE_DNE) {
+ if (want_state == MDSMap::STATE_DNE) {
suicide(); // we could do something more graceful here
}
timer.init();
- if (wanted_state==MDSMap::STATE_BOOT && g_conf->mds_standby_replay)
+ if (wanted_state==MDSMap::STATE_BOOT && g_conf->mds_standby_replay) {
wanted_state = MDSMap::STATE_STANDBY_REPLAY;
+ }
+
// starting beacon. this will induce an MDSMap from the monitor
want_state = wanted_state;
if (wanted_state==MDSMap::STATE_STANDBY_REPLAY ||
standby_for_rank = MDSMap::MDS_STANDBY_ANY;
else
standby_for_rank = MDSMap::MDS_STANDBY_NAME;
- } else if (!standby_type && !standby_for_name.empty())
+ } else if (standby_type == MDSMap::STATE_NULL && !standby_for_name.empty())
standby_for_rank = MDSMap::MDS_MATCHED_ACTIVE;
beacon_start();
// keep old map, for a moment
MDSMap *oldmap = mdsmap;
int oldwhoami = whoami;
- int oldstate = state;
+ MDSMap::DaemonState oldstate = state;
entity_addr_t addr;
// decode and process
goto out;
} else if (state == MDSMap::STATE_STANDBY_REPLAY) {
- if (standby_type && standby_type != MDSMap::STATE_STANDBY_REPLAY) {
+ if (standby_type != MDSMap::STATE_NULL && standby_type != MDSMap::STATE_STANDBY_REPLAY) {
want_state = standby_type;
beacon_send();
state = oldstate;
}
-void MDS::request_state(int s)
+void MDS::request_state(MDSMap::DaemonState s)
{
dout(3) << "request_state " << ceph_mds_state_name(s) << dendl;
want_state = s;
if (is_standby_replay())
standby_replaying = true;
- standby_type = 0;
+ standby_type = MDSMap::STATE_NULL;
calc_recovery_set();
void MDS::suicide()
{
assert(mds_lock.is_locked());
- want_state = CEPH_MDS_STATE_DNE; // whatever.
+ want_state = MDSMap::STATE_DNE; // whatever.
dout(1) << "suicide. wanted " << ceph_mds_state_name(want_state)
<< ", now " << ceph_mds_state_name(state) << dendl;
int incarnation;
int standby_for_rank;
- int standby_type;
+ MDSMap::DaemonState standby_type; // one of STANDBY_REPLAY, ONESHOT_REPLAY
string standby_for_name;
bool standby_replaying; // true if current replay pass is in standby-replay mode
protected:
// -- MDS state --
- int last_state;
- int state; // my confirmed state
- int want_state; // the state i want
+ MDSMap::DaemonState last_state;
+ MDSMap::DaemonState state; // my confirmed state
+ MDSMap::DaemonState want_state; // the state i want
list<Context*> waiting_for_active, waiting_for_replay, waiting_for_reconnect, waiting_for_resolve;
list<Context*> replay_queue;
bool is_stopped() { return mdsmap->is_stopped(whoami); }
- void request_state(int s);
+ void request_state(MDSMap::DaemonState s);
ceph_tid_t issue_tid() { return ++last_tid; }
}
// start up, shutdown
- int init(int wanted_state=MDSMap::STATE_BOOT);
+ int init(MDSMap::DaemonState wanted_state=MDSMap::STATE_BOOT);
// admin socket handling
friend class MDSSocketHook;
::encode(name, bl);
::encode(rank, bl);
::encode(inc, bl);
- ::encode(state, bl);
+ ::encode((int32_t)state, bl);
::encode(state_seq, bl);
::encode(addr, bl);
::encode(laggy_since, bl);
::encode(name, bl);
::encode(rank, bl);
::encode(inc, bl);
- ::encode(state, bl);
+ ::encode((int32_t)state, bl);
::encode(state_seq, bl);
::encode(addr, bl);
::encode(laggy_since, bl);
::decode(name, bl);
::decode(rank, bl);
::decode(inc, bl);
- ::decode(state, bl);
+ ::decode((int32_t&)(state), bl);
::decode(state_seq, bl);
::decode(addr, bl);
::decode(laggy_since, bl);
class MDSMap {
public:
- // mds states
- /*
- static const int STATE_DNE = CEPH_MDS_STATE_DNE; // down, never existed.
- static const int STATE_DESTROYING = CEPH_MDS_STATE_DESTROYING; // down, existing, semi-destroyed.
- static const int STATE_FAILED = CEPH_MDS_STATE_FAILED; // down, active subtrees; needs to be recovered.
- */
- static const int STATE_STOPPED = CEPH_MDS_STATE_STOPPED; // down, once existed, but no subtrees. empty log.
- static const int STATE_BOOT = CEPH_MDS_STATE_BOOT; // up, boot announcement. destiny unknown.
-
- static const int STATE_STANDBY = CEPH_MDS_STATE_STANDBY; // up, idle. waiting for assignment by monitor.
- static const int STATE_STANDBY_REPLAY = CEPH_MDS_STATE_STANDBY_REPLAY; // up, replaying active node; ready to take over.
- static const int STATE_ONESHOT_REPLAY = CEPH_MDS_STATE_REPLAYONCE; //up, replaying active node journal to verify it, then shutting down
-
- static const int STATE_CREATING = CEPH_MDS_STATE_CREATING; // up, creating MDS instance (new journal, idalloc..).
- static const int STATE_STARTING = CEPH_MDS_STATE_STARTING; // up, starting prior stopped MDS instance.
-
- static const int STATE_REPLAY = CEPH_MDS_STATE_REPLAY; // up, starting prior failed instance. scanning journal.
- static const int STATE_RESOLVE = CEPH_MDS_STATE_RESOLVE; // up, disambiguating distributed operations (import, rename, etc.)
- static const int STATE_RECONNECT = CEPH_MDS_STATE_RECONNECT; // up, reconnect to clients
- static const int STATE_REJOIN = CEPH_MDS_STATE_REJOIN; // up, replayed journal, rejoining distributed cache
- static const int STATE_CLIENTREPLAY = CEPH_MDS_STATE_CLIENTREPLAY; // up, active
- static const int STATE_ACTIVE = CEPH_MDS_STATE_ACTIVE; // up, active
- static const int STATE_STOPPING = CEPH_MDS_STATE_STOPPING; // up, exporting metadata (-> standby or out)
+ /* These states are the union of the set of possible states of an MDS daemon,
+ * and the set of possible states of an MDS rank */
+ typedef enum {
+ // States of an MDS daemon not currently holding a rank
+ // ====================================================
+ STATE_NULL = 0, // null value for fns returning this type.
+ STATE_BOOT = CEPH_MDS_STATE_BOOT, // up, boot announcement. destiny unknown.
+ STATE_STANDBY = CEPH_MDS_STATE_STANDBY, // up, idle. waiting for assignment by monitor.
+ STATE_STANDBY_REPLAY = CEPH_MDS_STATE_STANDBY_REPLAY, // up, replaying active node, ready to take over.
+
+ // States of an MDS rank, and of any MDS daemon holding that rank
+ // ==============================================================
+ STATE_STOPPED = CEPH_MDS_STATE_STOPPED, // down, once existed, but no subtrees. empty log. may not be held by a daemon.
+ STATE_ONESHOT_REPLAY = CEPH_MDS_STATE_REPLAYONCE, // up, replaying active node journal to verify it, then shutting down
+
+ STATE_CREATING = CEPH_MDS_STATE_CREATING, // up, creating MDS instance (new journal, idalloc..).
+ STATE_STARTING = CEPH_MDS_STATE_STARTING, // up, starting prior stopped MDS instance.
+
+ STATE_REPLAY = CEPH_MDS_STATE_REPLAY, // up, starting prior failed instance. scanning journal.
+ STATE_RESOLVE = CEPH_MDS_STATE_RESOLVE, // up, disambiguating distributed operations (import, rename, etc.)
+ STATE_RECONNECT = CEPH_MDS_STATE_RECONNECT, // up, reconnect to clients
+ STATE_REJOIN = CEPH_MDS_STATE_REJOIN, // up, replayed journal, rejoining distributed cache
+ STATE_CLIENTREPLAY = CEPH_MDS_STATE_CLIENTREPLAY, // up, active
+ STATE_ACTIVE = CEPH_MDS_STATE_ACTIVE, // up, active
+ STATE_STOPPING = CEPH_MDS_STATE_STOPPING, // up, exporting metadata (-> standby or out)
+ STATE_DNE = CEPH_MDS_STATE_DNE // down, rank does not exist
+
+ /*
+ * In addition to explicit states, an MDS rank implicitly in state:
+ * - STOPPED if it is not currently associated with an MDS daemon gid but it
+ * is in MDSMap::stopped
+ * - FAILED if it is not currently associated with an MDS daemon gid but it
+ * is in MDSMap::failed
+ * - DNE if it is not currently associated with an MDS daemon gid and it is
+ * missing from both MDSMap::failed and MDSMap::stopped
+ */
+ } DaemonState;
// indicate startup standby preferences for MDS
// of course, if they have a specific rank to follow, they just set that!
string name;
int32_t rank;
int32_t inc;
- int32_t state;
+ MDSMap::DaemonState state;
version_t state_seq;
entity_addr_t addr;
utime_t laggy_since;
if (p->second.state >= STATE_CLIENTREPLAY && p->second.state <= STATE_STOPPING)
s.insert(p->second.rank);
}
- void get_mds_set(set<int>& s, int state) {
+ void get_mds_set(set<int>& s, DaemonState state) {
for (map<uint64_t,mds_info_t>::const_iterator p = mds_info.begin();
p != mds_info.end();
++p)
bool is_dne(int m) const { return in.count(m) == 0; }
bool is_dne_gid(uint64_t gid) const { return mds_info.count(gid) == 0; }
- int get_state(int m) const {
+ /**
+ * Get MDS rank state if the rank is up, else STATE_NULL
+ */
+ DaemonState get_state(int m) const {
map<int32_t,uint64_t>::const_iterator u = up.find(m);
if (u == up.end())
- return 0;
+ return STATE_NULL;
return get_state_gid(u->second);
}
- int get_state_gid(uint64_t gid) const {
+
+ /**
+ * Get MDS daemon status by GID
+ */
+ DaemonState get_state_gid(uint64_t gid) const {
map<uint64_t,mds_info_t>::const_iterator i = mds_info.find(gid);
if (i == mds_info.end())
- return 0;
+ return STATE_NULL;
return i->second.state;
}
uint64_t global_id;
string name;
- __u32 state;
+ MDSMap::DaemonState state;
version_t seq;
__s32 standby_for_rank;
string standby_for_name;
public:
MMDSBeacon() : PaxosServiceMessage(MSG_MDS_BEACON, 0, HEAD_VERSION) { }
- MMDSBeacon(const uuid_d &f, uint64_t g, string& n, epoch_t les, int st, version_t se) :
+ MMDSBeacon(const uuid_d &f, uint64_t g, string& n, epoch_t les, MDSMap::DaemonState st, version_t se) :
PaxosServiceMessage(MSG_MDS_BEACON, les, HEAD_VERSION),
fsid(f), global_id(g), name(n), state(st), seq(se),
standby_for_rank(-1) {
uint64_t get_global_id() { return global_id; }
string& get_name() { return name; }
epoch_t get_last_epoch_seen() { return version; }
- int get_state() { return state; }
+ MDSMap::DaemonState get_state() { return state; }
version_t get_seq() { return seq; }
const char *get_type_name() const { return "mdsbeacon"; }
int get_standby_for_rank() { return standby_for_rank; }
paxos_encode();
::encode(fsid, payload);
::encode(global_id, payload);
- ::encode(state, payload);
+ ::encode((__u32)state, payload);
::encode(seq, payload);
::encode(name, payload);
::encode(standby_for_rank, payload);
paxos_decode(p);
::decode(fsid, p);
::decode(global_id, p);
- ::decode(state, p);
+ ::decode((__u32&)state, p);
::decode(seq, p);
::decode(name, p);
::decode(standby_for_rank, p);
bool MDSMonitor::preprocess_beacon(MMDSBeacon *m)
{
- int state = m->get_state();
+ MDSMap::DaemonState state = m->get_state();
uint64_t gid = m->get_global_id();
version_t seq = m->get_seq();
MDSMap::mds_info_t info;
dout(12) << "prepare_beacon " << *m << " from " << m->get_orig_source_inst() << dendl;
entity_addr_t addr = m->get_orig_source_inst().addr;
uint64_t gid = m->get_global_id();
- int state = m->get_state();
+ MDSMap::DaemonState state = m->get_state();
version_t seq = m->get_seq();
// Ignore beacons if filesystem is disabled
r = -EINVAL;
return true;
}
- int64_t state;
+ int32_t state;
if (!cmd_getval(g_ceph_context, cmdmap, "state", state)) {
ss << "error parsing 'state' string value '"
<< cmd_vartype_stringify(cmdmap["state"]) << "'";
}
if (!pending_mdsmap.is_dne_gid(gid)) {
MDSMap::mds_info_t& info = pending_mdsmap.get_info_gid(gid);
- info.state = state;
+ info.state = MDSMap::DaemonState(state);
stringstream ss;
ss << "set mds gid " << gid << " to state " << state << " " << ceph_mds_state_name(state);
r = 0;