]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: do not reopen MonitorDBStore during startup
authorSage Weil <sage@inktank.com>
Wed, 26 Jun 2013 13:01:40 +0000 (06:01 -0700)
committerSage Weil <sage@inktank.com>
Wed, 3 Jul 2013 23:17:52 +0000 (16:17 -0700)
level doesn't seem to like this when it races with an internal compaction
attempt (see below).  Instead, let the store get opened by the ceph_mon
caller, and pull a bit of the logic into the caller to make the flow a
little easier to follow.

    -2> 2013-06-25 17:49:25.184490 7f4d439f8780 10 needs_conversion
    -1> 2013-06-25 17:49:25.184495 7f4d4065c700  5 asok(0x13b1460) entry start
     0> 2013-06-25 17:49:25.316908 7f4d3fe5b700 -1 *** Caught signal (Segmentation fault) **
 in thread 7f4d3fe5b700

 ceph version 0.64-667-g089cba8 (089cba8fc0e8ae8aef9a3111cba7342ecd0f8314)
 1: ceph-mon() [0x649f0a]
 2: (()+0xfcb0) [0x7f4d435dccb0]
 3: (leveldb::Table::BlockReader(void*, leveldb::ReadOptions const&, leveldb::Slice const&)+0x154) [0x806e54]
 4: ceph-mon() [0x808840]
 5: ceph-mon() [0x808b39]
 6: ceph-mon() [0x806540]
 7: (leveldb::DBImpl::DoCompactionWork(leveldb::DBImpl::CompactionState*)+0xdd) [0x7f363d]
 8: (leveldb::DBImpl::BackgroundCompaction()+0x2c0) [0x7f4210]
 9: (leveldb::DBImpl::BackgroundCall()+0x68) [0x7f4cc8]
 10: ceph-mon() [0x80b3af]
 11: (()+0x7e9a) [0x7f4d435d4e9a]
 12: (clone()+0x6d) [0x7f4d4196bccd]
 NOTE: a copy of the executable, or `objdump -rdS <executable>` is needed to interpret this.

Signed-off-by: Sage Weil <sage@inktank.com>
(cherry picked from commit ea1f316e5de21487ae034a1aa929068ba23ac525)

src/ceph_mon.cc
src/mon/Monitor.cc
src/mon/Monitor.h

index a70db47b3513bb387f7c7c7d9da2c776b180b13d..e1e8c2b82cf37372c0bf215a5c351e1c9e099a69 100644 (file)
@@ -289,26 +289,36 @@ int main(int argc, const char **argv)
   common_init_finish(g_ceph_context);
   global_init_chdir(g_ceph_context);
 
-  {
-    Monitor::StoreConverter converter(g_conf->mon_data);
-    int ret = converter.needs_conversion();
-    if (ret > 0) {
-      assert(!converter.convert());
-    } else if (ret < 0) {
-      derr << "found errors while attempting to convert the monitor store: "
-           << cpp_strerror(ret) << dendl;
+  MonitorDBStore *store = new MonitorDBStore(g_conf->mon_data);
+
+  Monitor::StoreConverter converter(g_conf->mon_data, store);
+  if (store->open(std::cerr) < 0) {
+    int ret = store->create_and_open(std::cerr);
+    if (ret < 0) {
+      derr << "failed to create new leveldb store" << dendl;
       prefork.exit(1);
     }
-  }
 
-  MonitorDBStore *store = new MonitorDBStore(g_conf->mon_data);
-  err = store->open(std::cerr);
-  if (err < 0) {
-    cerr << argv[0] << ": error opening mon data store at '"
-         << g_conf->mon_data << "': " << cpp_strerror(err) << std::endl;
+    ret = converter.needs_conversion();
+    if (ret < 0) {
+      derr << "found errors while validating legacy unconverted monitor store: "
+           << cpp_strerror(ret) << dendl;
+      prefork.exit(1);
+    }
+    if (ret > 0) {
+      cout << "converting monitor store, please do not interrupt..." << std::endl;
+      int r = converter.convert();
+      if (r) {
+       derr << "failed to convert monitor store: " << cpp_strerror(r) << dendl;
+       prefork.exit(1);
+      }
+    }
+  } else if (converter.is_converting()) {
+    derr << "there is an on-going (maybe aborted?) conversion." << dendl;
+    derr << "you should check what happened" << dendl;
+    derr << "remove store.db to restart conversion" << dendl;
     prefork.exit(1);
   }
-  assert(err == 0);
 
   bufferlist magicbl;
   err = store->get(Monitor::MONITOR_NAME, "magic", magicbl);
index 1ca6de2987e517e2a38b4fb3c4b60612ee7a78e3..42fc15c5905bf7b7fcdfdb9623f090afcec3ef33 100644 (file)
@@ -4285,46 +4285,39 @@ bool Monitor::StoreConverter::_check_gv_store()
 
 int Monitor::StoreConverter::needs_conversion()
 {
+  bufferlist magicbl;
   int ret = 0;
 
   dout(10) << __func__ << dendl;
   _init();
-  if (db->open(std::cerr) < 0) {
-    dout(1) << "unable to open monitor store at " << g_conf->mon_data << dendl;
-    dout(1) << "check for old monitor store format" << dendl;
-    int err = store->mount();
-    if (err < 0) {
-      if (err == -ENOENT) {
-        derr << "unable to mount monitor store: "
-             << cpp_strerror(err) << dendl;
-      } else {
-        derr << "it appears that another monitor is running: "
-             << cpp_strerror(err) << dendl;
-      }
-      ret = err;
-      goto out;
-    }
-    assert(err == 0);
-    bufferlist magicbl;
-    if (store->exists_bl_ss("magic", 0)) {
-      if (_check_gv_store()) {
-       dout(1) << "found old GV monitor store format "
-               << "-- should convert!" << dendl;
-       ret = 1;
-      } else {
-       dout(0) << "Existing monitor store has not been converted "
-               << "to 0.52 (bobtail) format" << dendl;
-       assert(0 == "Existing store has not been converted to 0.52 format");
-      }
+
+  int err = store->mount();
+  if (err < 0) {
+    if (err == -ENOENT) {
+      derr << "unable to mount monitor store: "
+          << cpp_strerror(err) << dendl;
+    } else {
+      derr << "it appears that another monitor is running: "
+          << cpp_strerror(err) << dendl;
     }
-    assert(!store->umount());
-  } else {
-    if (db->exists("mon_convert", "on_going")) {
-      ret = -EEXIST;
-      derr << "there is an on-going (maybe aborted?) conversion." << dendl;
-      derr << "you should check what happened" << dendl;
+    ret = err;
+    goto out;
+  }
+  assert(err == 0);
+
+  if (store->exists_bl_ss("magic", 0)) {
+    if (_check_gv_store()) {
+      dout(1) << "found old GV monitor store format "
+             << "-- should convert!" << dendl;
+      ret = 1;
+    } else {
+      dout(0) << "Existing monitor store has not been converted "
+             << "to 0.52 (bobtail) format" << dendl;
+      assert(0 == "Existing store has not been converted to 0.52 format");
     }
   }
+  assert(!store->umount());
+
 out:
   _deinit();
   return ret;
index 2508aa7f3d303a787c4b7fb027ec9817ee387251..9e31bebd6d9c617cf8810830c09ebdb25e329ffe 100644 (file)
@@ -1445,7 +1445,7 @@ private:
 public:
   class StoreConverter {
     const string path;
-    boost::scoped_ptr<MonitorDBStore> db;
+    MonitorDBStore *db;
     boost::scoped_ptr<MonitorStore> store;
 
     set<version_t> gvs;
@@ -1455,8 +1455,8 @@ public:
     version_t highest_accepted_pn;
 
    public:
-    StoreConverter(const string &path)
-      : path(path), db(NULL), store(NULL),
+    StoreConverter(string path, MonitorDBStore *d)
+      : path(path), db(d), store(NULL),
        highest_last_pn(0), highest_accepted_pn(0)
     { }
 
@@ -1469,20 +1469,20 @@ public:
     int needs_conversion();
     int convert();
 
+    bool is_converting() {
+      return db->exists("mon_convert", "on_going");
+    }
+
    private:
 
     bool _check_gv_store();
 
     void _init() {
-      MonitorDBStore *db_ptr = new MonitorDBStore(path);
-      db.reset(db_ptr);
-
       MonitorStore *store_ptr = new MonitorStore(path);
       store.reset(store_ptr);
     }
 
     void _deinit() {
-      db.reset(NULL);
       store.reset(NULL);
     }