]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
journal: cleanup shutdown handling
authorJason Dillaman <dillaman@redhat.com>
Fri, 14 Aug 2015 20:22:39 +0000 (16:22 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 6 Nov 2015 01:42:42 +0000 (20:42 -0500)
Avoid the case where an intrusive_ptr could be created/destroyed
during shutdown due to resetting the journal header watch.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/journal/JournalMetadata.cc
src/journal/JournalMetadata.h

index bd486f5cae90656205af077a1d2796dc446e2ba5..d1e26df03fbcf326f3e44ff9bbbdcb54c1eb858e 100644 (file)
@@ -64,7 +64,15 @@ void JournalMetadata::init(Context *on_init) {
 
 void JournalMetadata::shutdown() {
   assert(m_initialized);
-  m_initialized = false;
+  {
+    Mutex::Locker locker(m_lock);
+    m_initialized = false;
+
+    if (m_watch_handle != 0) {
+      m_ioctx.unwatch2(m_watch_handle);
+      m_watch_handle = 0;
+    }
+  }
 
   if (m_timer != NULL) {
     Mutex::Locker locker(m_timer_lock);
@@ -79,12 +87,8 @@ void JournalMetadata::shutdown() {
     m_finisher = NULL;
   }
 
-  if (m_watch_handle != 0) {
-    m_ioctx.unwatch2(m_watch_handle);
-    librados::Rados rados(m_ioctx);
-    rados.watch_flush();
-    m_watch_handle = 0;
-  }
+  librados::Rados rados(m_ioctx);
+  rados.watch_flush();
 
   m_async_op_tracker.wait_for_ops();
   m_ioctx.aio_flush();
@@ -321,11 +325,16 @@ void JournalMetadata::handle_commit_position_task() {
 }
 
 void JournalMetadata::schedule_watch_reset() {
-  Mutex::Locker locker(m_timer_lock);
+  assert(m_timer_lock.is_locked());
   m_timer->add_event_after(0.1, new C_WatchReset(this));
 }
 
 void JournalMetadata::handle_watch_reset() {
+  assert(m_timer_lock.is_locked());
+  if (!m_initialized) {
+    return;
+  }
+
   int r = m_ioctx.watch2(m_oid, &m_watch_handle, &m_watch_ctx);
   if (r < 0) {
     lderr(m_cct) << __func__ << ": failed to watch journal"
@@ -348,7 +357,11 @@ void JournalMetadata::handle_watch_notify(uint64_t notify_id, uint64_t cookie) {
 
 void JournalMetadata::handle_watch_error(int err) {
   lderr(m_cct) << "journal watch error: " << cpp_strerror(err) << dendl;
-  schedule_watch_reset();
+  Mutex::Locker locker(m_lock);
+  Mutex::Locker timer_locker(m_timer_lock);
+  if (m_initialized && err != -ENOENT) {
+    schedule_watch_reset();
+  }
 }
 
 uint64_t JournalMetadata::allocate_commit_tid(uint64_t object_num,
@@ -432,8 +445,10 @@ void JournalMetadata::notify_update() {
 void JournalMetadata::async_notify_update() {
   ldout(m_cct, 10) << "async notifying journal header update" << dendl;
 
+  C_AioNotify *ctx = new C_AioNotify(this);
   librados::AioCompletion *comp =
-    librados::Rados::aio_create_completion(NULL, NULL, NULL);
+    librados::Rados::aio_create_completion(ctx, NULL,
+                                           utils::rados_ctx_callback);
 
   bufferlist bl;
   int r = m_ioctx.aio_notify(m_oid, comp, bl, 5000, NULL);
@@ -442,4 +457,8 @@ void JournalMetadata::async_notify_update() {
   comp->release();
 }
 
+void JournalMetadata::handle_notified(int r) {
+  ldout(m_cct, 10) << "notified journal header update: r=" << r << dendl;
+}
+
 } // namespace journal
index 0a933b019563c93184c2ca4d15e9f870b2a9bd91..ea477c73911ecbeb6a0997d9cb332982b909a303 100644 (file)
@@ -148,27 +148,50 @@ private:
   };
 
   struct C_WatchReset : public Context {
-    JournalMetadataPtr journal_metadata;
+    JournalMetadata *journal_metadata;
 
     C_WatchReset(JournalMetadata *_journal_metadata)
-      : journal_metadata(_journal_metadata) {}
-
+      : journal_metadata(_journal_metadata) {
+      journal_metadata->m_async_op_tracker.start_op();
+    }
+    virtual ~C_WatchReset() {
+      journal_metadata->m_async_op_tracker.finish_op();
+    }
     virtual void finish(int r) {
       journal_metadata->handle_watch_reset();
     }
   };
 
   struct C_CommitPositionTask : public Context {
-    JournalMetadataPtr journal_metadata;
+    JournalMetadata *journal_metadata;
 
     C_CommitPositionTask(JournalMetadata *_journal_metadata)
-      : journal_metadata(_journal_metadata) {}
-
+      : journal_metadata(_journal_metadata) {
+      journal_metadata->m_async_op_tracker.start_op();
+    }
+    virtual ~C_CommitPositionTask() {
+      journal_metadata->m_async_op_tracker.finish_op();
+    }
     virtual void finish(int r) {
       journal_metadata->handle_commit_position_task();
     };
   };
 
+  struct C_AioNotify : public Context {
+    JournalMetadata* journal_metadata;
+
+    C_AioNotify(JournalMetadata *_journal_metadata)
+      : journal_metadata(_journal_metadata) {
+      journal_metadata->m_async_op_tracker.start_op();
+    }
+    virtual ~C_AioNotify() {
+      journal_metadata->m_async_op_tracker.finish_op();
+    }
+    virtual void finish(int r) {
+      journal_metadata->handle_notified(r);
+    }
+  };
+
   struct C_NotifyUpdate : public Context {
     JournalMetadata* journal_metadata;
     Context *on_safe;
@@ -280,6 +303,7 @@ private:
   void handle_watch_reset();
   void handle_watch_notify(uint64_t notify_id, uint64_t cookie);
   void handle_watch_error(int err);
+  void handle_notified(int r);
 };
 
 } // namespace journal