summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoao Eduardo Luis <joao.luis@inktank.com>2013-04-19 17:28:06 +0100
committerJoao Eduardo Luis <joao.luis@inktank.com>2013-04-22 22:53:14 +0100
commit9ba32404aebb9c223ad3254d463df9b47352753f (patch)
treea1b193369e6108f05df4c14128e4f3a08771546d
parent4b9a2a39c9126c79358e3b7d276b6ecc36946f8f (diff)
downloadceph-9ba32404aebb9c223ad3254d463df9b47352753f.tar.gz
mon: Monitor: backup monmap prior to starting a store sync
If by fate we end up attempting a store sync after failing at least one before, we might not have a monmap to read from the store to backup. Therefore, in that case, we shall backup the current monmap being used by the monitor. Signed-off-by: Joao Eduardo Luis <joao.luis@inktank.com>
-rw-r--r--src/mon/Monitor.cc58
-rw-r--r--src/mon/Monitor.h4
2 files changed, 54 insertions, 8 deletions
diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc
index e3d33ce9d60..31d68677378 100644
--- a/src/mon/Monitor.cc
+++ b/src/mon/Monitor.cc
@@ -408,7 +408,7 @@ int Monitor::preinit()
// We have a potentially inconsistent store state in hands. Get rid of it
// and start fresh.
bool clear_store = false;
- if (store->get("mon_sync", "in_sync") > 0) {
+ if (is_sync_on_going()) {
dout(1) << __func__ << " clean up potentially inconsistent store state"
<< dendl;
clear_store = true;
@@ -421,8 +421,12 @@ int Monitor::preinit()
if (clear_store) {
set<string> sync_prefixes = get_sync_targets_names();
- sync_prefixes.insert("mon_sync");
store->clear(sync_prefixes);
+
+ MonitorDBStore::Transaction t;
+ t.erase("mon_sync", "in_sync");
+ t.erase("mon_sync", "force_sync");
+ store->apply_transaction(t);
}
}
@@ -1276,6 +1280,47 @@ void Monitor::sync_requester_abort()
}
/**
+ *
+ */
+void Monitor::sync_store_init()
+{
+ MonitorDBStore::Transaction t;
+ t.put("mon_sync", "in_sync", 1);
+
+ bufferlist latest_monmap;
+ int err = monmon()->get_monmap(latest_monmap);
+ if (err < 0) {
+ if (err != -ENOENT) {
+ derr << __func__
+ << " something wrong happened while reading the store: "
+ << cpp_strerror(err) << dendl;
+ assert(0 == "error reading the store");
+ return; // this is moot
+ } else {
+ dout(10) << __func__ << " backup current monmap" << dendl;
+ monmap->encode(latest_monmap, get_quorum_features());
+ }
+ }
+
+ t.put("mon_sync", "latest_monmap", latest_monmap);
+
+ store->apply_transaction(t);
+}
+
+void Monitor::sync_store_cleanup()
+{
+ MonitorDBStore::Transaction t;
+ t.erase("mon_sync", "in_sync");
+ t.erase("mon_sync", "latest_monmap");
+ store->apply_transaction(t);
+}
+
+bool Monitor::is_sync_on_going()
+{
+ return store->exists("mon_sync", "in_sync");
+}
+
+/**
* Start Sync process
*
* Create SyncEntity instances for the leader and the provider;
@@ -1321,9 +1366,8 @@ void Monitor::sync_start(entity_inst_t &other)
targets.insert("mon_sync");
store->clear(targets);
- MonitorDBStore::Transaction t;
- t.put("mon_sync", "in_sync", 1);
- store->apply_transaction(t);
+
+ sync_store_init();
// assume 'other' as the leader. We will update the leader once we receive
// a reply to the sync start.
@@ -1618,9 +1662,7 @@ void Monitor::handle_sync_finish_reply(MMonSync *m)
paxos->reapply_all_versions();
- MonitorDBStore::Transaction t;
- t.erase("mon_sync", "in_sync");
- store->apply_transaction(t);
+ sync_store_cleanup();
init_paxos();
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index f5512efd775..c08942d4a50 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -364,6 +364,10 @@ private:
}
};
+ void sync_store_init();
+ void sync_store_cleanup();
+ bool is_sync_on_going();
+
/**
* Send a heartbeat message to another entity.
*