]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common: use mono clock for HeartbeatMap 17827/head
authorKefu Chai <kchai@redhat.com>
Wed, 20 Sep 2017 07:13:35 +0000 (15:13 +0800)
committerKefu Chai <kchai@redhat.com>
Thu, 21 Sep 2017 17:12:13 +0000 (01:12 +0800)
to avoid problems when admin sets system clock.

see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53901 for the reason
why we cannot use atomic<time_point>.

Signed-off-by: Kefu Chai <kchai@redhat.com>
Signed-off-by: Xinze Chi <xinze@xsky.com>
src/common/HeartbeatMap.cc
src/common/HeartbeatMap.h
src/common/WorkQueue.h

index ae1f8e8faae78a66eda32f5cb083ddd730ff1d85..62a703f911459d3615d3f3cfca764b8607c2a93d 100644 (file)
@@ -28,7 +28,6 @@ namespace ceph {
 HeartbeatMap::HeartbeatMap(CephContext *cct)
   : m_cct(cct),
     m_rwlock("HeartbeatMap::m_rwlock"),
-    m_inject_unhealthy_until(0),
     m_unhealthy_workers(0),
     m_total_workers(0)
 {
@@ -64,12 +63,11 @@ void HeartbeatMap::remove_worker(const heartbeat_handle_d *h)
   delete h;
 }
 
-bool HeartbeatMap::_check(const heartbeat_handle_d *h, const char *who, time_t now)
+bool HeartbeatMap::_check(const heartbeat_handle_d *h, const char *who,
+                         ceph::coarse_mono_clock::rep now)
 {
   bool healthy = true;
-  time_t was;
-
-  was = h->timeout;
+  auto was = h->timeout.load();
   if (was && was < now) {
     ldout(m_cct, 1) << who << " '" << h->name << "'"
                    << " had timed out after " << h->grace << dendl;
@@ -86,11 +84,14 @@ bool HeartbeatMap::_check(const heartbeat_handle_d *h, const char *who, time_t n
   return healthy;
 }
 
-void HeartbeatMap::reset_timeout(heartbeat_handle_d *h, time_t grace, time_t suicide_grace)
+void HeartbeatMap::reset_timeout(heartbeat_handle_d *h,
+                                ceph::coarse_mono_clock::rep grace,
+                                ceph::coarse_mono_clock::rep suicide_grace)
 {
   ldout(m_cct, 20) << "reset_timeout '" << h->name << "' grace " << grace
                   << " suicide " << suicide_grace << dendl;
-  time_t now = time(NULL);
+  auto now = chrono::duration_cast<chrono::seconds>(
+              ceph::coarse_mono_clock::now().time_since_epoch()).count();
   _check(h, "reset_timeout", now);
 
   h->timeout = now + grace;
@@ -106,7 +107,8 @@ void HeartbeatMap::reset_timeout(heartbeat_handle_d *h, time_t grace, time_t sui
 void HeartbeatMap::clear_timeout(heartbeat_handle_d *h)
 {
   ldout(m_cct, 20) << "clear_timeout '" << h->name << "'" << dendl;
-  time_t now = time(NULL);
+  auto now = chrono::duration_cast<std::chrono::seconds>(
+              ceph::coarse_mono_clock::now().time_since_epoch()).count();
   _check(h, "clear_timeout", now);
   h->timeout = 0;
   h->suicide_timeout = 0;
@@ -117,16 +119,18 @@ bool HeartbeatMap::is_healthy()
   int unhealthy = 0;
   int total = 0;
   m_rwlock.get_read();
-  time_t now = time(NULL);
+  auto now = ceph::coarse_mono_clock::now();
   if (m_cct->_conf->heartbeat_inject_failure) {
     ldout(m_cct, 0) << "is_healthy injecting failure for next " << m_cct->_conf->heartbeat_inject_failure << " seconds" << dendl;
-    m_inject_unhealthy_until = now + m_cct->_conf->heartbeat_inject_failure;
+    m_inject_unhealthy_until = now + std::chrono::seconds(m_cct->_conf->heartbeat_inject_failure);
     m_cct->_conf->set_val("heartbeat_inject_failure", "0");
   }
 
   bool healthy = true;
   if (now < m_inject_unhealthy_until) {
-    ldout(m_cct, 0) << "is_healthy = false, injected failure for next " << (m_inject_unhealthy_until - now) << " seconds" << dendl;
+    auto sec = std::chrono::duration_cast<std::chrono::seconds>(m_inject_unhealthy_until - now).count();
+    ldout(m_cct, 0) << "is_healthy = false, injected failure for next "
+                    << sec << " seconds" << dendl;
     healthy = false;
   }
 
@@ -134,7 +138,8 @@ bool HeartbeatMap::is_healthy()
        p != m_workers.end();
        ++p) {
     heartbeat_handle_d *h = *p;
-    if (!_check(h, "is_healthy", now)) {
+    auto epoch = chrono::duration_cast<chrono::seconds>(now.time_since_epoch()).count();
+    if (!_check(h, "is_healthy", epoch)) {
       healthy = false;
       unhealthy++;
     }
index 4e9b314667f4d53e5641373f870c1722f92d5ce7..f7ffd9eb62090d03d9f32d800350292660475634 100644 (file)
@@ -18,9 +18,9 @@
 #include <list>
 #include <atomic>
 #include <string>
-
 #include <pthread.h>
 
+#include "common/ceph_time.h"
 #include "RWLock.h"
 
 class CephContext;
@@ -41,6 +41,7 @@ namespace ceph {
 struct heartbeat_handle_d {
   const std::string name;
   pthread_t thread_id;
+  // TODO: use atomic<time_point>, once we can ditch GCC 4.8
   std::atomic<unsigned> timeout = { 0 }, suicide_timeout = { 0 };
   time_t grace, suicide_grace;
   std::list<heartbeat_handle_d*>::iterator list_item;
@@ -57,7 +58,9 @@ class HeartbeatMap {
   void remove_worker(const heartbeat_handle_d *h);
 
   // reset the timeout so that it expects another touch within grace amount of time
-  void reset_timeout(heartbeat_handle_d *h, time_t grace, time_t suicide_grace);
+  void reset_timeout(heartbeat_handle_d *h,
+                    ceph::coarse_mono_clock::rep grace,
+                    ceph::coarse_mono_clock::rep suicide_grace);
   // clear the timeout so that it's not checked on
   void clear_timeout(heartbeat_handle_d *h);
 
@@ -79,12 +82,13 @@ class HeartbeatMap {
  private:
   CephContext *m_cct;
   RWLock m_rwlock;
-  time_t m_inject_unhealthy_until;
+  ceph::coarse_mono_clock::time_point m_inject_unhealthy_until;
   std::list<heartbeat_handle_d*> m_workers;
   std::atomic<unsigned> m_unhealthy_workers = { 0 };
   std::atomic<unsigned> m_total_workers = { 0 };
 
-  bool _check(const heartbeat_handle_d *h, const char *who, time_t now);
+  bool _check(const heartbeat_handle_d *h, const char *who,
+             ceph::coarse_mono_clock::rep now);
 };
 
 }
index d3eff47bdf844e61139a0de11df33d159c79a447..fcdd43b35d7d88a3316bdaa8cd29191c95be079d 100644 (file)
@@ -42,8 +42,8 @@ public:
     friend class ThreadPool;
     CephContext *cct;
     heartbeat_handle_d *hb;
-    time_t grace;
-    time_t suicide_grace;
+    ceph::coarse_mono_clock::rep grace;
+    ceph::coarse_mono_clock::rep suicide_grace;
   public:
     TPHandle(
       CephContext *cct,