]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: add wait_for_latest_osdmap()
authorGreg Farnum <greg@inktank.com>
Fri, 15 Nov 2013 23:48:55 +0000 (15:48 -0800)
committerSage Weil <sage@inktank.com>
Fri, 6 Dec 2013 22:37:26 +0000 (14:37 -0800)
There are times when users may need to make sure the client has the
latest osdmap, for example after sending a mon command modifying
pool properties.

Signed-off-by: Sage Weil <sage@inktank.com>
Signed-off-by: Greg Farnum <greg@inktank.com>
squash "librados: add wait_for_latest_osdmap()"

src/include/rados/librados.hpp
src/librados/RadosClient.cc
src/librados/RadosClient.h
src/librados/librados.cc
src/osdc/Objecter.cc
src/osdc/Objecter.h
src/test/librados/misc.cc

index 488acf418f46d3933405f67850b9895502d974cd..a2c7465b0b746f94d6d0d389f60af027ad9fa549 100644 (file)
@@ -804,6 +804,9 @@ namespace librados
     int cluster_stat(cluster_stat_t& result);
     int cluster_fsid(std::string *fsid);
 
+    /// get/wait for the most recent osdmap
+    int wait_for_latest_osdmap();
+
     /*
      * pool aio
      *
index 6ec901de508b1ae82616713f08f47dd03e0aab2c..9f63ffb60dd1aed0c03b23dbf11b2069285b1793 100644 (file)
@@ -388,6 +388,24 @@ void librados::RadosClient::wait_for_osdmap()
   }
 }
 
+int librados::RadosClient::wait_for_latest_osdmap()
+{
+  Mutex mylock("RadosClient::wait_for_latest_osdmap");
+  Cond cond;
+  bool done;
+
+  lock.Lock();
+  objecter->wait_for_latest_osdmap(new C_SafeCond(&mylock, &cond, &done));
+  lock.Unlock();
+
+  mylock.Lock();
+  while (!done)
+    cond.Wait(mylock);
+  mylock.Unlock();
+
+  return 0;
+}
+
 int librados::RadosClient::pool_list(std::list<std::string>& v)
 {
   Mutex::Locker l(lock);
index 92c65c6a75bb96a946bcc8883b1af6c5be448786..df72bb3405ab6d4593136ecf83018fadeb460565 100644 (file)
@@ -83,6 +83,8 @@ public:
 
   uint64_t get_instance_id();
 
+  int wait_for_latest_osdmap();
+
   int create_ioctx(const char *name, IoCtxImpl **io);
 
   int get_fsid(std::string *s);
index 7f0ae1fcc327629d91d57f8187bf5e140d0a6635..823cbd0bbf20ad81ae3ef696f2fe677cbd128aa4 100644 (file)
@@ -1602,6 +1602,11 @@ int librados::Rados::cluster_fsid(string *fsid)
   return client->get_fsid(fsid);
 }
 
+int librados::Rados::wait_for_latest_osdmap()
+{
+  return client->wait_for_latest_osdmap();
+}
+
 librados::PoolAsyncCompletion *librados::Rados::pool_async_create_completion()
 {
   PoolAsyncCompletionImpl *c = new PoolAsyncCompletionImpl;
index c0cd0fb6c2aae5a46f8358f5ade012750ecf359e..f004a5c6f355fb5f34a7312ff878994e75cb38e1 100644 (file)
@@ -969,6 +969,43 @@ void Objecter::wait_for_osd_map()
   lock.Unlock();
 }
 
+struct C_Objecter_GetVersion : public Context {
+  Objecter *objecter;
+  uint64_t oldest, newest;
+  Context *fin;
+  C_Objecter_GetVersion(Objecter *o, Context *c)
+    : objecter(o), oldest(0), newest(0), fin(c) {}
+  void finish(int r) {
+    if (r >= 0)
+      objecter->_get_latest_version(oldest, newest, fin);
+    else if (r == -EAGAIN) { // try again as instructed
+      objecter->wait_for_latest_osdmap(fin);
+    } else {
+      // it doesn't return any other error codes!
+      assert(0);
+    }
+  }
+};
+
+void Objecter::wait_for_latest_osdmap(Context *fin)
+{
+  ldout(cct, 10) << __func__ << dendl;
+  C_Objecter_GetVersion *c = new C_Objecter_GetVersion(this, fin);
+  monc->get_version("osdmap", &c->newest, &c->oldest, c);
+}
+
+void Objecter::_get_latest_version(epoch_t oldest, epoch_t newest, Context *fin)
+{
+  if (osdmap->get_epoch() >= newest) {
+  ldout(cct, 10) << __func__ << " latest " << newest << ", have it" << dendl;
+    if (fin)
+      fin->complete(0);
+    return;
+  }
+
+  ldout(cct, 10) << __func__ << " latest " << newest << ", waiting" << dendl;
+  wait_for_new_map(fin, newest, 0);
+}
 
 void Objecter::maybe_request_map()
 {
index 67171590a9d0a78e72be6ce346df350ccb5795b1..fc03dbc1b78db33f0403b7d4868375e3bfb531f5 100644 (file)
@@ -1383,6 +1383,8 @@ private:
   void set_client_incarnation(int inc) { client_inc = inc; }
 
   void wait_for_new_map(Context *c, epoch_t epoch, int err=0);
+  void wait_for_latest_osdmap(Context *fin);
+  void _get_latest_version(epoch_t oldest, epoch_t neweset, Context *fin);
 
   /** Get the current set of global op flags */
   int get_global_op_flags() { return global_op_flags; }
index 9abac9c412a6fe2f533f9d7871de1ffcfe76923c..ec77cb009dc9306660fc6036d01c7b1b62f7af55 100644 (file)
@@ -46,6 +46,16 @@ TEST(LibRadosMisc, ClusterFSID) {
   ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
 }
 
+TEST(LibRadosMisc, WaitOSDMapPP) {
+  Rados cluster;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
+
+  ASSERT_EQ(0, cluster.wait_for_latest_osdmap());
+
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
 static std::string read_key_from_tmap(IoCtx& ioctx, const std::string &obj,
                                      const std::string &key)
 {