From: Jason Dillaman Date: Fri, 14 Aug 2015 20:22:39 +0000 (-0400) Subject: journal: cleanup shutdown handling X-Git-Tag: v10.0.1~102^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=87e3e05bc21f42d3e3fb5c820a8fbee7ce710d9e;p=ceph.git journal: cleanup shutdown handling 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 --- diff --git a/src/journal/JournalMetadata.cc b/src/journal/JournalMetadata.cc index bd486f5cae90..d1e26df03fbc 100644 --- a/src/journal/JournalMetadata.cc +++ b/src/journal/JournalMetadata.cc @@ -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 diff --git a/src/journal/JournalMetadata.h b/src/journal/JournalMetadata.h index 0a933b019563..ea477c73911e 100644 --- a/src/journal/JournalMetadata.h +++ b/src/journal/JournalMetadata.h @@ -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