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.78~206^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1829d2c9fd13f2cbae4e192c9feb553047dad42c;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 --- diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index add1bb0ff14b..4cd47eb6f89f 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -102,7 +102,9 @@ int64_t librados::RadosClient::lookup_pool(const char *name) lock.Lock(); - wait_for_osdmap(); + int r = wait_for_osdmap(); + if (r < 0) + return r; int64_t ret = osdmap.lookup_pg_pool_name(name); pool_cache_rwl.get_write(); lock.Unlock(); @@ -129,7 +131,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; @@ -140,7 +144,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; @@ -406,15 +412,34 @@ 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::wait_for_latest_osdmap() @@ -438,7 +463,9 @@ int librados::RadosClient::wait_for_latest_osdmap() 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) @@ -534,7 +561,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(); @@ -563,13 +592,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 onfinish; } diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index f9cc1f7e54c3..325f4563d023 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -79,7 +79,7 @@ private: void *log_cb_arg; string log_watch; - void wait_for_osdmap(); + int wait_for_osdmap(); public: Finisher finisher;