From: Josh Durgin Date: Mon, 3 Feb 2014 20:53:15 +0000 (-0800) Subject: librados: add timeout to wait_for_osdmap() X-Git-Tag: v0.67.6~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2aa0d7589283fe5879a966601fbfe690816cc4a1;p=ceph.git librados: add timeout to wait_for_osdmap() This is used by several pool operations independent of the objecter, including rados_ioctx_create() to look up the pool id in the first osdmap. Unfortunately we can't just rely on WaitInterval returning ETIMEDOUT, since it may also get interrupted by a signal, so we can't avoid keeping track of time explicitly here. Signed-off-by: Josh Durgin (cherry picked from commit 1829d2c9fd13f2cbae4e192c9feb553047dad42c) Conflicts: src/librados/RadosClient.cc --- diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index 8a5f499ec152..236ac397656f 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -101,7 +101,9 @@ const char *librados::RadosClient::get_pool_name(int64_t pool_id) int librados::RadosClient::pool_get_auid(uint64_t pool_id, unsigned long long *auid) { Mutex::Locker l(lock); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; const pg_pool_t *pg = osdmap.get_pg_pool(pool_id); if (!pg) return -ENOENT; @@ -112,7 +114,9 @@ int librados::RadosClient::pool_get_auid(uint64_t pool_id, unsigned long long *a int librados::RadosClient::pool_get_name(uint64_t pool_id, std::string *s) { Mutex::Locker l(lock); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; const char *str = osdmap.get_pool_name(pool_id); if (!str) return -ENOENT; @@ -357,21 +361,42 @@ bool librados::RadosClient::_dispatch(Message *m) return true; } -void librados::RadosClient::wait_for_osdmap() +int librados::RadosClient::wait_for_osdmap() { assert(lock.is_locked()); + + utime_t timeout; + if (cct->_conf->rados_mon_op_timeout > 0) + timeout.set_from_double(cct->_conf->rados_mon_op_timeout); + if (osdmap.get_epoch() == 0) { ldout(cct, 10) << __func__ << " waiting" << dendl; - while (osdmap.get_epoch() == 0) - cond.Wait(lock); + utime_t start = ceph_clock_now(cct); + + while (osdmap.get_epoch() == 0) { + cond.WaitInterval(cct, lock, timeout); + + utime_t elapsed = ceph_clock_now(cct) - start; + if (!timeout.is_zero() && elapsed > timeout) + break; + } + ldout(cct, 10) << __func__ << " done waiting" << dendl; + + if (osdmap.get_epoch() == 0) { + lderr(cct) << "timed out waiting for first osdmap from monitors" << dendl; + return -ETIMEDOUT; + } } + return 0; } int librados::RadosClient::pool_list(std::list& v) { Mutex::Locker l(lock); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; for (map::const_iterator p = osdmap.get_pools().begin(); p != osdmap.get_pools().end(); ++p) @@ -468,7 +493,9 @@ int librados::RadosClient::pool_create_async(string& name, PoolAsyncCompletionIm int librados::RadosClient::pool_delete(const char *name) { lock.Lock(); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; int tmp_pool_id = osdmap.lookup_pg_pool_name(name); if (tmp_pool_id < 0) { lock.Unlock(); @@ -497,13 +524,15 @@ int librados::RadosClient::pool_delete(const char *name) int librados::RadosClient::pool_delete_async(const char *name, PoolAsyncCompletionImpl *c) { Mutex::Locker l(lock); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; int tmp_pool_id = osdmap.lookup_pg_pool_name(name); if (tmp_pool_id < 0) return -ENOENT; Context *onfinish = new C_PoolAsync_Safe(c); - int r = objecter->delete_pool(tmp_pool_id, onfinish); + r = objecter->delete_pool(tmp_pool_id, onfinish); if (r < 0) { delete c; delete onfinish; diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 4f616d453313..043230d482fa 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -70,7 +70,7 @@ private: void *log_cb_arg; string log_watch; - void wait_for_osdmap(); + int wait_for_osdmap(); public: Finisher finisher;