From: Greg Farnum Date: Fri, 15 Nov 2013 23:48:55 +0000 (-0800) Subject: librados: add wait_for_latest_osdmap() X-Git-Tag: v0.75~98^2~44 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0b0d1e8e422ee6b0caf6b5adde8e34a5d2ed193f;p=ceph.git librados: add wait_for_latest_osdmap() 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 Signed-off-by: Greg Farnum squash "librados: add wait_for_latest_osdmap()" --- diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 488acf418f46..a2c7465b0b74 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -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 * diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index 6ec901de508b..9f63ffb60dd1 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -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& v) { Mutex::Locker l(lock); diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 92c65c6a75bb..df72bb3405ab 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -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); diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 7f0ae1fcc327..823cbd0bbf20 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -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; diff --git a/src/osdc/Objecter.cc b/src/osdc/Objecter.cc index c0cd0fb6c2aa..f004a5c6f355 100644 --- a/src/osdc/Objecter.cc +++ b/src/osdc/Objecter.cc @@ -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() { diff --git a/src/osdc/Objecter.h b/src/osdc/Objecter.h index 67171590a9d0..fc03dbc1b78d 100644 --- a/src/osdc/Objecter.h +++ b/src/osdc/Objecter.h @@ -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; } diff --git a/src/test/librados/misc.cc b/src/test/librados/misc.cc index 9abac9c412a6..ec77cb009dc9 100644 --- a/src/test/librados/misc.cc +++ b/src/test/librados/misc.cc @@ -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) {