]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: move journal support classes to journal namespace
authorJason Dillaman <dillaman@redhat.com>
Tue, 15 Dec 2015 15:34:24 +0000 (10:34 -0500)
committerJason Dillaman <dillaman@redhat.com>
Fri, 15 Jan 2016 15:40:27 +0000 (10:40 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
22 files changed:
src/CMakeLists.txt
src/librbd/AioImageRequest.cc
src/librbd/Journal.cc
src/librbd/Journal.h
src/librbd/JournalReplay.cc [deleted file]
src/librbd/JournalReplay.h [deleted file]
src/librbd/JournalTypes.cc [deleted file]
src/librbd/JournalTypes.h [deleted file]
src/librbd/Makefile.am
src/librbd/journal/Entries.cc [new file with mode: 0644]
src/librbd/journal/Entries.h [new file with mode: 0644]
src/librbd/journal/Replay.cc [new file with mode: 0644]
src/librbd/journal/Replay.h [new file with mode: 0644]
src/librbd/operation/Request.h
src/test/Makefile-client.am
src/test/encoding/types.h
src/test/librbd/journal/test_Entries.cc [new file with mode: 0644]
src/test/librbd/journal/test_Replay.cc [new file with mode: 0644]
src/test/librbd/mock/MockJournal.h
src/test/librbd/test_JournalEntries.cc [deleted file]
src/test/librbd/test_JournalReplay.cc [deleted file]
src/tools/rbd/action/Journal.cc

index d2c4cfda6242d23ee64b78eada28b9d8d650bcf2..10d86c2ab7f6f700845705aebc1b40f3b3254550 100644 (file)
@@ -974,8 +974,6 @@ if(${WITH_RBD})
     librbd/ImageWatcher.cc
     librbd/internal.cc
     librbd/Journal.cc
-    librbd/JournalReplay.cc
-    librbd/JournalTypes.cc
     librbd/librbd.cc
     librbd/LibrbdAdminSocketHook.cc
     librbd/LibrbdWriteback.cc
@@ -988,6 +986,8 @@ if(${WITH_RBD})
     librbd/image/RefreshParentRequest.cc
     librbd/image/RefreshRequest.cc
     librbd/image/SetSnapRequest.cc
+    librbd/journal/Entries.cc
+    librbd/journal/Replay.cc
     librbd/object_map/InvalidateRequest.cc
     librbd/object_map/LockRequest.cc
     librbd/object_map/Request.cc
index 104148b49b20920d4a35f00ac66c59bc56bbc780..975096f3fbcd7b5957320191acabf6ca1bd94b06 100644 (file)
@@ -10,7 +10,7 @@
 #include "librbd/ImageWatcher.h"
 #include "librbd/internal.h"
 #include "librbd/Journal.h"
-#include "librbd/JournalTypes.h"
+#include "librbd/journal/Entries.h"
 #include "include/rados/librados.hpp"
 #include "osdc/Striper.h"
 
index 903a4581a81d7df61c52aa06de21a477b3ec4847..fa5448e1ea48648c92c79cbbca91dd440cbfa975 100644 (file)
@@ -7,8 +7,8 @@
 #include "librbd/AioObjectRequest.h"
 #include "librbd/ExclusiveLock.h"
 #include "librbd/ImageCtx.h"
-#include "librbd/JournalReplay.h"
-#include "librbd/JournalTypes.h"
+#include "librbd/journal/Entries.h"
+#include "librbd/journal/Replay.h"
 #include "librbd/Utils.h"
 #include "journal/Journaler.h"
 #include "journal/ReplayEntry.h"
@@ -498,7 +498,7 @@ void Journal::handle_initialized(int r) {
   }
 
   transition_state(STATE_REPLAYING, 0);
-  m_journal_replay = new JournalReplay(m_image_ctx);
+  m_journal_replay = new journal::Replay(m_image_ctx);
   m_journaler->start_replay(&m_replay_handler);
 }
 
index 0ea9ae428827a641a7a74c780f06058766d47665..d9a48dbb76b9ecf18ec69f290c1ef86629563e52 100644 (file)
@@ -26,10 +26,10 @@ namespace librbd {
 class AioCompletion;
 class AioObjectRequest;
 class ImageCtx;
-class JournalReplay;
 
 namespace journal {
 class EventEntry;
+class Replay;
 }
 
 class Journal {
@@ -217,7 +217,7 @@ private:
 
   bool m_blocking_writes;
 
-  JournalReplay *m_journal_replay;
+  journal::Replay *m_journal_replay;
 
   ::journal::Future wait_event(Mutex &lock, uint64_t tid, Context *on_safe);
 
diff --git a/src/librbd/JournalReplay.cc b/src/librbd/JournalReplay.cc
deleted file mode 100644 (file)
index 3379f11..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "librbd/JournalReplay.h"
-#include "librbd/AioCompletion.h"
-#include "librbd/AioImageRequest.h"
-#include "librbd/ImageCtx.h"
-#include "librbd/internal.h"
-
-#define dout_subsys ceph_subsys_rbd
-#undef dout_prefix
-#define dout_prefix *_dout << "librbd::JournalReplay: "
-
-namespace librbd {
-
-JournalReplay::JournalReplay(ImageCtx &image_ctx)
-  : m_image_ctx(image_ctx), m_lock("JournalReplay::m_lock"), m_ret_val(0) {
-}
-
-JournalReplay::~JournalReplay() {
-  assert(m_aio_completions.empty());
-}
-
-int JournalReplay::process(bufferlist::iterator it, Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << dendl;
-
-  RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
-  journal::EventEntry event_entry;
-  try {
-    ::decode(event_entry, it);
-  } catch (const buffer::error &err) {
-    lderr(cct) << "failed to decode event entry: " << err.what() << dendl;
-    return -EINVAL;
-  }
-
-  boost::apply_visitor(EventVisitor(this, on_safe), event_entry.event);
-  return 0;
-}
-
-int JournalReplay::flush() {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << dendl;
-
-  Mutex::Locker locker(m_lock);
-  while (!m_aio_completions.empty()) {
-    m_cond.Wait(m_lock);
-  }
-  return m_ret_val;
-}
-
-void JournalReplay::handle_event(const journal::AioDiscardEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": AIO discard event" << dendl;
-
-  AioCompletion *aio_comp = create_aio_completion(on_safe);
-  AioImageRequest::aio_discard(&m_image_ctx, aio_comp, event.offset,
-                               event.length);
-}
-
-void JournalReplay::handle_event(const journal::AioWriteEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": AIO write event" << dendl;
-
-  bufferlist data = event.data;
-  AioCompletion *aio_comp = create_aio_completion(on_safe);
-  AioImageRequest::aio_write(&m_image_ctx, aio_comp, event.offset, event.length,
-                             data.c_str(), 0);
-}
-
-void JournalReplay::handle_event(const journal::AioFlushEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": AIO flush event" << dendl;
-
-  AioCompletion *aio_comp = create_aio_completion(on_safe);
-  AioImageRequest::aio_flush(&m_image_ctx, aio_comp);
-}
-
-  void JournalReplay::handle_event(const journal::OpFinishEvent &event,
-                                  Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Op finish event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapCreateEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap create event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapRemoveEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap remove event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapRenameEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap rename event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapProtectEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap protect event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapUnprotectEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap unprotect event"
-                 << dendl;
-}
-
-void JournalReplay::handle_event(const journal::SnapRollbackEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Snap rollback start event"
-                 << dendl;
-}
-
-void JournalReplay::handle_event(const journal::RenameEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Rename event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::ResizeEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Resize start event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::FlattenEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": Flatten start event" << dendl;
-}
-
-void JournalReplay::handle_event(const journal::UnknownEvent &event,
-                                Context *on_safe) {
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": unknown event" << dendl;
-  on_safe->complete(0);
-}
-
-AioCompletion *JournalReplay::create_aio_completion(Context *on_safe) {
-  Mutex::Locker locker(m_lock);
-  AioCompletion *aio_comp = AioCompletion::create(this, aio_completion_callback,
-                                                  nullptr);
-  m_aio_completions.insert(std::pair<AioCompletion*,Context*>(
-                            aio_comp, on_safe));
-  return aio_comp;
-}
-
-void JournalReplay::handle_aio_completion(AioCompletion *aio_comp) {
-  Mutex::Locker locker(m_lock);
-
-  AioCompletions::iterator it = m_aio_completions.find(aio_comp);
-  assert(it != m_aio_completions.end());
-
-  int r = aio_comp->get_return_value();
-
-  CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << this << " " << __func__ << ": aio_comp=" << aio_comp << ", "
-                 << "r=" << r << dendl;
-
-  Context *on_safe = it->second;
-  on_safe->complete(r);
-
-  if (r < 0 && m_ret_val == 0) {
-    m_ret_val = r;
-  }
-
-  m_aio_completions.erase(it);
-  if (m_aio_completions.empty())
-    m_cond.Signal();
-}
-
-void JournalReplay::aio_completion_callback(completion_t cb, void *arg) {
-  JournalReplay *journal_replay = reinterpret_cast<JournalReplay *>(arg);
-  AioCompletion *aio_comp = reinterpret_cast<AioCompletion *>(cb);
-
-  journal_replay->handle_aio_completion(aio_comp);
-  aio_comp->release();
-}
-
-} // namespace librbd
diff --git a/src/librbd/JournalReplay.h b/src/librbd/JournalReplay.h
deleted file mode 100644 (file)
index 6b5711a..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#ifndef CEPH_LIBRBD_JOURNAL_REPLAY_H
-#define CEPH_LIBRBD_JOURNAL_REPLAY_H
-
-#include "include/int_types.h"
-#include "include/buffer_fwd.h"
-#include "include/rbd/librbd.hpp"
-#include "common/Cond.h"
-#include "common/Mutex.h"
-#include "librbd/JournalTypes.h"
-#include <boost/variant.hpp>
-#include <map>
-
-namespace librbd {
-
-class AioCompletion;
-class ImageCtx;
-
-class JournalReplay {
-public:
-  JournalReplay(ImageCtx &image_ctx);
-  ~JournalReplay();
-
-  int process(bufferlist::iterator it, Context *on_safe = NULL);
-  int flush();
-
-private:
-  typedef std::map<AioCompletion*,Context*> AioCompletions;
-
-  struct EventVisitor : public boost::static_visitor<void> {
-    JournalReplay *journal_replay;
-    Context *on_safe;
-
-    EventVisitor(JournalReplay *_journal_replay, Context *_on_safe)
-      : journal_replay(_journal_replay), on_safe(_on_safe) {
-    }
-
-    template <typename Event>
-    inline void operator()(const Event &event) const {
-      journal_replay->handle_event(event, on_safe);
-    }
-  };
-
-  ImageCtx &m_image_ctx;
-
-  Mutex m_lock;
-  Cond m_cond;
-
-  AioCompletions m_aio_completions;
-  int m_ret_val;
-
-  void handle_event(const journal::AioDiscardEvent &event, Context *on_safe);
-  void handle_event(const journal::AioWriteEvent &event, Context *on_safe);
-  void handle_event(const journal::AioFlushEvent &event, Context *on_safe);
-  void handle_event(const journal::OpFinishEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapCreateEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapRemoveEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapRenameEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapProtectEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapUnprotectEvent &event, Context *on_safe);
-  void handle_event(const journal::SnapRollbackEvent &event, Context *on_safe);
-  void handle_event(const journal::RenameEvent &event, Context *on_safe);
-  void handle_event(const journal::ResizeEvent &event, Context *on_safe);
-  void handle_event(const journal::FlattenEvent &event, Context *on_safe);
-  void handle_event(const journal::UnknownEvent &event, Context *on_safe);
-
-  AioCompletion *create_aio_completion(Context *on_safe);
-  void handle_aio_completion(AioCompletion *aio_comp);
-
-  static void aio_completion_callback(completion_t cb, void *arg);
-};
-
-} // namespace librbd
-
-#endif // CEPH_LIBRBD_JOURNAL_REPLAY_H
diff --git a/src/librbd/JournalTypes.cc b/src/librbd/JournalTypes.cc
deleted file mode 100644 (file)
index cda35aa..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "librbd/JournalTypes.h"
-#include "include/assert.h"
-#include "include/stringify.h"
-#include "common/Formatter.h"
-
-namespace librbd {
-namespace journal {
-
-namespace {
-
-class GetEventTypeVistor : public boost::static_visitor<EventType> {
-public:
-  template <typename Event>
-  inline EventType operator()(const Event &event) const {
-    return Event::EVENT_TYPE;
-  }
-};
-
-class EncodeEventVisitor : public boost::static_visitor<void> {
-public:
-  EncodeEventVisitor(bufferlist &bl) : m_bl(bl) {
-  }
-
-  template <typename Event>
-  inline void operator()(const Event &event) const {
-    ::encode(static_cast<uint32_t>(Event::EVENT_TYPE), m_bl);
-    event.encode(m_bl);
-  }
-private:
-  bufferlist &m_bl;
-};
-
-class DecodeEventVisitor : public boost::static_visitor<void> {
-public:
-  DecodeEventVisitor(__u8 version, bufferlist::iterator &iter)
-    : m_version(version), m_iter(iter) {
-  }
-
-  template <typename Event>
-  inline void operator()(Event &event) const {
-    event.decode(m_version, m_iter);
-  }
-private:
-  __u8 m_version;
-  bufferlist::iterator &m_iter;
-};
-
-class DumpEventVisitor : public boost::static_visitor<void> {
-public:
-  DumpEventVisitor(Formatter *formatter) : m_formatter(formatter) {}
-
-  template <typename Event>
-  inline void operator()(const Event &event) const {
-    EventType event_type = Event::EVENT_TYPE;
-    m_formatter->dump_string("event_type", stringify(event_type));
-    event.dump(m_formatter);
-  }
-private:
-  ceph::Formatter *m_formatter;
-};
-
-} // anonymous namespace
-
-void AioDiscardEvent::encode(bufferlist& bl) const {
-  ::encode(offset, bl);
-  ::encode(length, bl);
-}
-
-void AioDiscardEvent::decode(__u8 version, bufferlist::iterator& it) {
-  ::decode(offset, it);
-  ::decode(length, it);
-}
-
-void AioDiscardEvent::dump(Formatter *f) const {
-  f->dump_unsigned("offset", offset);
-  f->dump_unsigned("length", length);
-}
-
-void AioWriteEvent::encode(bufferlist& bl) const {
-  ::encode(offset, bl);
-  ::encode(length, bl);
-  ::encode(data, bl);
-}
-
-void AioWriteEvent::decode(__u8 version, bufferlist::iterator& it) {
-  ::decode(offset, it);
-  ::decode(length, it);
-  ::decode(data, it);
-}
-
-void AioWriteEvent::dump(Formatter *f) const {
-  f->dump_unsigned("offset", offset);
-  f->dump_unsigned("length", length);
-}
-
-void AioFlushEvent::encode(bufferlist& bl) const {
-}
-
-void AioFlushEvent::decode(__u8 version, bufferlist::iterator& it) {
-}
-
-void AioFlushEvent::dump(Formatter *f) const {
-}
-
-void OpEventBase::encode(bufferlist& bl) const {
-  ::encode(tid, bl);
-}
-
-void OpEventBase::decode(__u8 version, bufferlist::iterator& it) {
-  ::decode(tid, it);
-}
-
-void OpEventBase::dump(Formatter *f) const {
-  f->dump_unsigned("tid", tid);
-}
-
-void SnapEventBase::encode(bufferlist& bl) const {
-  OpStartEventBase::encode(bl);
-  ::encode(snap_name, bl);
-}
-
-void SnapEventBase::decode(__u8 version, bufferlist::iterator& it) {
-  OpStartEventBase::decode(version, it);
-  ::decode(snap_name, it);
-}
-
-void SnapEventBase::dump(Formatter *f) const {
-  OpStartEventBase::dump(f);
-  f->dump_string("snap_name", snap_name);
-}
-
-void SnapRenameEvent::encode(bufferlist& bl) const {
-  SnapEventBase::encode(bl);
-  ::encode(snap_id, bl);
-}
-
-void SnapRenameEvent::decode(__u8 version, bufferlist::iterator& it) {
-  SnapEventBase::decode(version, it);
-  ::decode(snap_id, it);
-}
-
-void SnapRenameEvent::dump(Formatter *f) const {
-  OpStartEventBase::dump(f);
-  f->dump_unsigned("src_snap_id", snap_id);
-  f->dump_string("dest_snap_name", snap_name);
-}
-
-void RenameEvent::encode(bufferlist& bl) const {
-  OpStartEventBase::encode(bl);
-  ::encode(image_name, bl);
-}
-
-void RenameEvent::decode(__u8 version, bufferlist::iterator& it) {
-  OpStartEventBase::decode(version, it);
-  ::decode(image_name, it);
-}
-
-void RenameEvent::dump(Formatter *f) const {
-  OpStartEventBase::dump(f);
-  f->dump_string("image_name", image_name);
-}
-
-void ResizeEvent::encode(bufferlist& bl) const {
-  OpStartEventBase::encode(bl);
-  ::encode(size, bl);
-}
-
-void ResizeEvent::decode(__u8 version, bufferlist::iterator& it) {
-  OpStartEventBase::decode(version, it);
-  ::decode(size, it);
-}
-
-void ResizeEvent::dump(Formatter *f) const {
-  OpStartEventBase::dump(f);
-  f->dump_unsigned("size", size);
-}
-
-void UnknownEvent::encode(bufferlist& bl) const {
-  assert(false);
-}
-
-void UnknownEvent::decode(__u8 version, bufferlist::iterator& it) {
-}
-
-void UnknownEvent::dump(Formatter *f) const {
-}
-
-EventType EventEntry::get_event_type() const {
-  return boost::apply_visitor(GetEventTypeVistor(), event);
-}
-
-void EventEntry::encode(bufferlist& bl) const {
-  ENCODE_START(1, 1, bl);
-  boost::apply_visitor(EncodeEventVisitor(bl), event);
-  ENCODE_FINISH(bl);
-}
-
-void EventEntry::decode(bufferlist::iterator& it) {
-  DECODE_START(1, it);
-
-  uint32_t event_type;
-  ::decode(event_type, it);
-
-  // select the correct payload variant based upon the encoded op
-  switch (event_type) {
-  case EVENT_TYPE_AIO_DISCARD:
-    event = AioDiscardEvent();
-    break;
-  case EVENT_TYPE_AIO_WRITE:
-    event = AioWriteEvent();
-    break;
-  case EVENT_TYPE_AIO_FLUSH:
-    event = AioFlushEvent();
-    break;
-  case EVENT_TYPE_OP_FINISH:
-    event = OpFinishEvent();
-    break;
-  case EVENT_TYPE_SNAP_CREATE:
-    event = SnapCreateEvent();
-    break;
-  case EVENT_TYPE_SNAP_REMOVE:
-    event = SnapRemoveEvent();
-    break;
-  case EVENT_TYPE_SNAP_RENAME:
-    event = SnapRenameEvent();
-    break;
-  case EVENT_TYPE_SNAP_PROTECT:
-    event = SnapProtectEvent();
-    break;
-  case EVENT_TYPE_SNAP_UNPROTECT:
-    event = SnapUnprotectEvent();
-    break;
-  case EVENT_TYPE_SNAP_ROLLBACK:
-    event = SnapRollbackEvent();
-    break;
-  case EVENT_TYPE_RENAME:
-    event = RenameEvent();
-    break;
-  case EVENT_TYPE_RESIZE:
-    event = ResizeEvent();
-    break;
-  case EVENT_TYPE_FLATTEN:
-    event = FlattenEvent();
-    break;
-  default:
-    event = UnknownEvent();
-    break;
-  }
-
-  boost::apply_visitor(DecodeEventVisitor(struct_v, it), event);
-  DECODE_FINISH(it);
-}
-
-void EventEntry::dump(Formatter *f) const {
-  boost::apply_visitor(DumpEventVisitor(f), event);
-}
-
-void EventEntry::generate_test_instances(std::list<EventEntry *> &o) {
-  o.push_back(new EventEntry(AioDiscardEvent()));
-  o.push_back(new EventEntry(AioDiscardEvent(123, 345)));
-
-  bufferlist bl;
-  bl.append(std::string(32, '1'));
-  o.push_back(new EventEntry(AioWriteEvent()));
-  o.push_back(new EventEntry(AioWriteEvent(123, 456, bl)));
-
-  o.push_back(new EventEntry(AioFlushEvent()));
-
-  o.push_back(new EventEntry(OpFinishEvent(123, -1)));
-
-  o.push_back(new EventEntry(SnapCreateEvent()));
-  o.push_back(new EventEntry(SnapCreateEvent(234, "snap")));
-
-  o.push_back(new EventEntry(SnapRemoveEvent()));
-  o.push_back(new EventEntry(SnapRemoveEvent(345, "snap")));
-
-  o.push_back(new EventEntry(SnapRenameEvent()));
-  o.push_back(new EventEntry(SnapRenameEvent(345, 1, "snap")));
-
-  o.push_back(new EventEntry(SnapProtectEvent()));
-  o.push_back(new EventEntry(SnapProtectEvent(456, "snap")));
-
-  o.push_back(new EventEntry(SnapUnprotectEvent()));
-  o.push_back(new EventEntry(SnapUnprotectEvent(567, "snap")));
-
-  o.push_back(new EventEntry(SnapRollbackEvent()));
-  o.push_back(new EventEntry(SnapRollbackEvent(678, "snap")));
-
-  o.push_back(new EventEntry(RenameEvent()));
-  o.push_back(new EventEntry(RenameEvent(789, "image name")));
-
-  o.push_back(new EventEntry(ResizeEvent()));
-  o.push_back(new EventEntry(ResizeEvent(890, 1234)));
-
-  o.push_back(new EventEntry(FlattenEvent(901)));
-}
-
-} // namespace journal
-} // namespace librbd
-
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::EventType &type) {
-  using namespace librbd::journal;
-
-  switch (type) {
-  case EVENT_TYPE_AIO_DISCARD:
-    out << "AioDiscard";
-    break;
-  case EVENT_TYPE_AIO_WRITE:
-    out << "AioWrite";
-    break;
-  case EVENT_TYPE_AIO_FLUSH:
-    out << "AioFlush";
-    break;
-  case EVENT_TYPE_OP_FINISH:
-    out << "OpFinish";
-    break;
-  case EVENT_TYPE_SNAP_CREATE:
-    out << "SnapCreate";
-    break;
-  case EVENT_TYPE_SNAP_REMOVE:
-    out << "SnapRemove";
-    break;
-  case EVENT_TYPE_SNAP_RENAME:
-    out << "SnapRename";
-    break;
-  case EVENT_TYPE_SNAP_PROTECT:
-    out << "SnapProtect";
-    break;
-  case EVENT_TYPE_SNAP_UNPROTECT:
-    out << "SnapUnprotect";
-    break;
-  case EVENT_TYPE_SNAP_ROLLBACK:
-    out << "SnapRollback";
-    break;
-  case EVENT_TYPE_RENAME:
-    out << "Rename";
-    break;
-  case EVENT_TYPE_RESIZE:
-    out << "Resize";
-    break;
-  case EVENT_TYPE_FLATTEN:
-    out << "Flatten";
-    break;
-  default:
-    out << "Unknown (" << static_cast<uint32_t>(type) << ")";
-    break;
-  }
-  return out;
-}
diff --git a/src/librbd/JournalTypes.h b/src/librbd/JournalTypes.h
deleted file mode 100644 (file)
index ce8ff03..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#ifndef CEPH_LIBRBD_JOURNAL_TYPES_H
-#define CEPH_LIBRBD_JOURNAL_TYPES_H
-
-#include "include/int_types.h"
-#include "include/buffer.h"
-#include "include/encoding.h"
-#include "include/types.h"
-#include <iosfwd>
-#include <boost/variant.hpp>
-
-namespace ceph {
-class Formatter;
-}
-
-namespace librbd {
-namespace journal {
-
-enum EventType {
-  EVENT_TYPE_AIO_DISCARD    = 0,
-  EVENT_TYPE_AIO_WRITE      = 1,
-  EVENT_TYPE_AIO_FLUSH      = 2,
-  EVENT_TYPE_OP_FINISH      = 3,
-  EVENT_TYPE_SNAP_CREATE    = 4,
-  EVENT_TYPE_SNAP_REMOVE    = 5,
-  EVENT_TYPE_SNAP_RENAME    = 6,
-  EVENT_TYPE_SNAP_PROTECT   = 7,
-  EVENT_TYPE_SNAP_UNPROTECT = 8,
-  EVENT_TYPE_SNAP_ROLLBACK  = 9,
-  EVENT_TYPE_RENAME         = 10,
-  EVENT_TYPE_RESIZE         = 11,
-  EVENT_TYPE_FLATTEN        = 12
-};
-
-struct AioDiscardEvent {
-  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_DISCARD;
-
-  uint64_t offset;
-  size_t length;
-
-  AioDiscardEvent() : offset(0), length(0) {
-  }
-  AioDiscardEvent(uint64_t _offset, size_t _length)
-    : offset(_offset), length(_length) {
-  }
-
-  void encode(bufferlist& bl) const;
-  void decode(__u8 version, bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-};
-
-struct AioWriteEvent {
-  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_WRITE;
-
-  uint64_t offset;
-  size_t length;
-  bufferlist data;
-
-  AioWriteEvent() : offset(0), length(0) {
-  }
-  AioWriteEvent(uint64_t _offset, size_t _length, const bufferlist &_data)
-    : offset(_offset), length(_length), data(_data) {
-  }
-
-  void encode(bufferlist& bl) const;
-  void decode(__u8 version, bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-};
-
-struct AioFlushEvent {
-  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_FLUSH;
-
-  void encode(bufferlist& bl) const;
-  void decode(__u8 version, bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-};
-
-struct OpEventBase {
-  uint64_t tid;
-
-  virtual void encode(bufferlist& bl) const;
-  virtual void decode(__u8 version, bufferlist::iterator& it);
-  virtual void dump(Formatter *f) const;
-
-protected:
-  OpEventBase() : tid(0) {
-  }
-  OpEventBase(uint64_t _tid) : tid(_tid) {
-  }
-  virtual ~OpEventBase() {}
-};
-
-struct OpStartEventBase : public OpEventBase {
-protected:
-  OpStartEventBase() {
-  }
-  OpStartEventBase(uint64_t tid) : OpEventBase(tid) {
-  }
-};
-
-struct OpFinishEvent : public OpEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_OP_FINISH;
-
-  int r;
-
-  OpFinishEvent() : r(0) {
-  }
-  OpFinishEvent(uint64_t tid, int _r) : OpEventBase(tid), r(_r) {
-  }
-};
-
-struct SnapEventBase : public OpStartEventBase {
-  std::string snap_name;
-
-  SnapEventBase() {
-  }
-  SnapEventBase(uint64_t tid, const std::string &_snap_name)
-    : OpStartEventBase(tid), snap_name(_snap_name) {
-  }
-
-  virtual void encode(bufferlist& bl) const;
-  virtual void decode(__u8 version, bufferlist::iterator& it);
-  virtual void dump(Formatter *f) const;
-};
-
-struct SnapCreateEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_CREATE;
-
-  SnapCreateEvent() {
-  }
-  SnapCreateEvent(uint64_t tid, const std::string &snap_name)
-    : SnapEventBase(tid, snap_name) {
-  }
-};
-
-struct SnapRemoveEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_REMOVE;
-
-  SnapRemoveEvent() {
-  }
-  SnapRemoveEvent(uint64_t tid, const std::string &snap_name)
-    : SnapEventBase(tid, snap_name) {
-  }
-};
-
-struct SnapRenameEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_RENAME;
-
-  uint64_t snap_id;
-
-  SnapRenameEvent() : snap_id(CEPH_NOSNAP) {
-  }
-  SnapRenameEvent(uint64_t tid, uint64_t src_snap_id,
-                  const std::string &dest_snap_name)
-    : SnapEventBase(tid, dest_snap_name), snap_id(src_snap_id) {
-  }
-
-  virtual void encode(bufferlist& bl) const;
-  virtual void decode(__u8 version, bufferlist::iterator& it);
-  virtual void dump(Formatter *f) const;
-};
-
-struct SnapProtectEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_PROTECT;
-
-  SnapProtectEvent() {
-  }
-  SnapProtectEvent(uint64_t tid, const std::string &snap_name)
-    : SnapEventBase(tid, snap_name) {
-  }
-};
-
-struct SnapUnprotectEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_UNPROTECT;
-
-  SnapUnprotectEvent() {
-  }
-  SnapUnprotectEvent(uint64_t tid, const std::string &snap_name)
-    : SnapEventBase(tid, snap_name) {
-  }
-};
-
-struct SnapRollbackEvent : public SnapEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_ROLLBACK;
-
-  SnapRollbackEvent() {
-  }
-  SnapRollbackEvent(uint64_t tid, const std::string &snap_name)
-    : SnapEventBase(tid, snap_name) {
-  }
-};
-
-struct RenameEvent : public OpStartEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_RENAME;
-
-  std::string image_name;
-
-  RenameEvent() {
-  }
-  RenameEvent(uint64_t tid, const std::string &_image_name)
-    : OpStartEventBase(tid), image_name(_image_name) {
-  }
-
-  virtual void encode(bufferlist& bl) const;
-  virtual void decode(__u8 version, bufferlist::iterator& it);
-  virtual void dump(Formatter *f) const;
-};
-
-struct ResizeEvent : public OpStartEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_RESIZE;
-
-  uint64_t size;
-
-  ResizeEvent() : size(0) {
-  }
-  ResizeEvent(uint64_t tid, uint64_t _size)
-    : OpStartEventBase(tid), size(_size) {
-  }
-
-  virtual void encode(bufferlist& bl) const;
-  virtual void decode(__u8 version, bufferlist::iterator& it);
-  virtual void dump(Formatter *f) const;
-};
-
-struct FlattenEvent : public OpStartEventBase {
-  static const EventType EVENT_TYPE = EVENT_TYPE_FLATTEN;
-
-  FlattenEvent() {
-  }
-  FlattenEvent(uint64_t tid) : OpStartEventBase(tid) {
-  }
-};
-
-struct UnknownEvent {
-  static const EventType EVENT_TYPE = static_cast<EventType>(-1);
-
-  void encode(bufferlist& bl) const;
-  void decode(__u8 version, bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-};
-
-typedef boost::variant<AioDiscardEvent,
-                       AioWriteEvent,
-                       AioFlushEvent,
-                       OpFinishEvent,
-                       SnapCreateEvent,
-                       SnapRemoveEvent,
-                       SnapRenameEvent,
-                       SnapProtectEvent,
-                       SnapUnprotectEvent,
-                       SnapRollbackEvent,
-                       RenameEvent,
-                       ResizeEvent,
-                       FlattenEvent,
-                       UnknownEvent> Event;
-
-struct EventEntry {
-  EventEntry() : event(UnknownEvent()) {
-  }
-  EventEntry(const Event &_event) : event(_event) {
-  }
-
-  Event event;
-
-  EventType get_event_type() const;
-
-  void encode(bufferlist& bl) const;
-  void decode(bufferlist::iterator& it);
-  void dump(Formatter *f) const;
-
-  static void generate_test_instances(std::list<EventEntry *> &o);
-};
-
-} // namespace journal
-} // namespace librbd
-
-std::ostream &operator<<(std::ostream &out,
-                         const librbd::journal::EventType &type);
-
-WRITE_CLASS_ENCODER(librbd::journal::EventEntry);
-
-#endif // CEPH_LIBRBD_JOURNAL_TYPES_H
index 153b69e4c81785013b68a4a17c05478f197cb6d0..c02ca981abe9862323c488cc29fb6d904189bb41 100644 (file)
@@ -1,5 +1,5 @@
 librbd_types_la_SOURCES = \
-       librbd/JournalTypes.cc \
+       librbd/journal/Entries.cc \
        librbd/WatchNotifyTypes.cc
 noinst_LTLIBRARIES += librbd_types.la
 
@@ -23,7 +23,6 @@ librbd_internal_la_SOURCES = \
        librbd/ImageWatcher.cc \
        librbd/internal.cc \
        librbd/Journal.cc \
-       librbd/JournalReplay.cc \
        librbd/LibrbdAdminSocketHook.cc \
        librbd/LibrbdWriteback.cc \
        librbd/ObjectMap.cc \
@@ -35,6 +34,7 @@ librbd_internal_la_SOURCES = \
        librbd/image/RefreshParentRequest.cc \
        librbd/image/RefreshRequest.cc \
        librbd/image/SetSnapRequest.cc \
+       librbd/journal/Replay.cc \
        librbd/object_map/InvalidateRequest.cc \
        librbd/object_map/LockRequest.cc \
        librbd/object_map/Request.cc \
@@ -97,8 +97,6 @@ noinst_HEADERS += \
        librbd/ImageWatcher.h \
        librbd/internal.h \
        librbd/Journal.h \
-       librbd/JournalReplay.h \
-       librbd/JournalTypes.h \
        librbd/LibrbdAdminSocketHook.h \
        librbd/LibrbdWriteback.h \
        librbd/ObjectMap.h \
@@ -114,6 +112,8 @@ noinst_HEADERS += \
        librbd/image/RefreshParentRequest.h \
        librbd/image/RefreshRequest.h \
        librbd/image/SetSnapRequest.h \
+       librbd/journal/Replay.h \
+       librbd/journal/Entries.h \
        librbd/object_map/InvalidateRequest.h \
        librbd/object_map/LockRequest.h \
        librbd/object_map/Request.h \
diff --git a/src/librbd/journal/Entries.cc b/src/librbd/journal/Entries.cc
new file mode 100644 (file)
index 0000000..fb4106b
--- /dev/null
@@ -0,0 +1,353 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/journal/Entries.h"
+#include "include/assert.h"
+#include "include/stringify.h"
+#include "common/Formatter.h"
+
+namespace librbd {
+namespace journal {
+
+namespace {
+
+class GetEventTypeVistor : public boost::static_visitor<EventType> {
+public:
+  template <typename Event>
+  inline EventType operator()(const Event &event) const {
+    return Event::EVENT_TYPE;
+  }
+};
+
+class EncodeEventVisitor : public boost::static_visitor<void> {
+public:
+  EncodeEventVisitor(bufferlist &bl) : m_bl(bl) {
+  }
+
+  template <typename Event>
+  inline void operator()(const Event &event) const {
+    ::encode(static_cast<uint32_t>(Event::EVENT_TYPE), m_bl);
+    event.encode(m_bl);
+  }
+private:
+  bufferlist &m_bl;
+};
+
+class DecodeEventVisitor : public boost::static_visitor<void> {
+public:
+  DecodeEventVisitor(__u8 version, bufferlist::iterator &iter)
+    : m_version(version), m_iter(iter) {
+  }
+
+  template <typename Event>
+  inline void operator()(Event &event) const {
+    event.decode(m_version, m_iter);
+  }
+private:
+  __u8 m_version;
+  bufferlist::iterator &m_iter;
+};
+
+class DumpEventVisitor : public boost::static_visitor<void> {
+public:
+  DumpEventVisitor(Formatter *formatter) : m_formatter(formatter) {}
+
+  template <typename Event>
+  inline void operator()(const Event &event) const {
+    EventType event_type = Event::EVENT_TYPE;
+    m_formatter->dump_string("event_type", stringify(event_type));
+    event.dump(m_formatter);
+  }
+private:
+  ceph::Formatter *m_formatter;
+};
+
+} // anonymous namespace
+
+void AioDiscardEvent::encode(bufferlist& bl) const {
+  ::encode(offset, bl);
+  ::encode(length, bl);
+}
+
+void AioDiscardEvent::decode(__u8 version, bufferlist::iterator& it) {
+  ::decode(offset, it);
+  ::decode(length, it);
+}
+
+void AioDiscardEvent::dump(Formatter *f) const {
+  f->dump_unsigned("offset", offset);
+  f->dump_unsigned("length", length);
+}
+
+void AioWriteEvent::encode(bufferlist& bl) const {
+  ::encode(offset, bl);
+  ::encode(length, bl);
+  ::encode(data, bl);
+}
+
+void AioWriteEvent::decode(__u8 version, bufferlist::iterator& it) {
+  ::decode(offset, it);
+  ::decode(length, it);
+  ::decode(data, it);
+}
+
+void AioWriteEvent::dump(Formatter *f) const {
+  f->dump_unsigned("offset", offset);
+  f->dump_unsigned("length", length);
+}
+
+void AioFlushEvent::encode(bufferlist& bl) const {
+}
+
+void AioFlushEvent::decode(__u8 version, bufferlist::iterator& it) {
+}
+
+void AioFlushEvent::dump(Formatter *f) const {
+}
+
+void OpEventBase::encode(bufferlist& bl) const {
+  ::encode(tid, bl);
+}
+
+void OpEventBase::decode(__u8 version, bufferlist::iterator& it) {
+  ::decode(tid, it);
+}
+
+void OpEventBase::dump(Formatter *f) const {
+  f->dump_unsigned("tid", tid);
+}
+
+void SnapEventBase::encode(bufferlist& bl) const {
+  OpStartEventBase::encode(bl);
+  ::encode(snap_name, bl);
+}
+
+void SnapEventBase::decode(__u8 version, bufferlist::iterator& it) {
+  OpStartEventBase::decode(version, it);
+  ::decode(snap_name, it);
+}
+
+void SnapEventBase::dump(Formatter *f) const {
+  OpStartEventBase::dump(f);
+  f->dump_string("snap_name", snap_name);
+}
+
+void SnapRenameEvent::encode(bufferlist& bl) const {
+  SnapEventBase::encode(bl);
+  ::encode(snap_id, bl);
+}
+
+void SnapRenameEvent::decode(__u8 version, bufferlist::iterator& it) {
+  SnapEventBase::decode(version, it);
+  ::decode(snap_id, it);
+}
+
+void SnapRenameEvent::dump(Formatter *f) const {
+  OpStartEventBase::dump(f);
+  f->dump_unsigned("src_snap_id", snap_id);
+  f->dump_string("dest_snap_name", snap_name);
+}
+
+void RenameEvent::encode(bufferlist& bl) const {
+  OpStartEventBase::encode(bl);
+  ::encode(image_name, bl);
+}
+
+void RenameEvent::decode(__u8 version, bufferlist::iterator& it) {
+  OpStartEventBase::decode(version, it);
+  ::decode(image_name, it);
+}
+
+void RenameEvent::dump(Formatter *f) const {
+  OpStartEventBase::dump(f);
+  f->dump_string("image_name", image_name);
+}
+
+void ResizeEvent::encode(bufferlist& bl) const {
+  OpStartEventBase::encode(bl);
+  ::encode(size, bl);
+}
+
+void ResizeEvent::decode(__u8 version, bufferlist::iterator& it) {
+  OpStartEventBase::decode(version, it);
+  ::decode(size, it);
+}
+
+void ResizeEvent::dump(Formatter *f) const {
+  OpStartEventBase::dump(f);
+  f->dump_unsigned("size", size);
+}
+
+void UnknownEvent::encode(bufferlist& bl) const {
+  assert(false);
+}
+
+void UnknownEvent::decode(__u8 version, bufferlist::iterator& it) {
+}
+
+void UnknownEvent::dump(Formatter *f) const {
+}
+
+EventType EventEntry::get_event_type() const {
+  return boost::apply_visitor(GetEventTypeVistor(), event);
+}
+
+void EventEntry::encode(bufferlist& bl) const {
+  ENCODE_START(1, 1, bl);
+  boost::apply_visitor(EncodeEventVisitor(bl), event);
+  ENCODE_FINISH(bl);
+}
+
+void EventEntry::decode(bufferlist::iterator& it) {
+  DECODE_START(1, it);
+
+  uint32_t event_type;
+  ::decode(event_type, it);
+
+  // select the correct payload variant based upon the encoded op
+  switch (event_type) {
+  case EVENT_TYPE_AIO_DISCARD:
+    event = AioDiscardEvent();
+    break;
+  case EVENT_TYPE_AIO_WRITE:
+    event = AioWriteEvent();
+    break;
+  case EVENT_TYPE_AIO_FLUSH:
+    event = AioFlushEvent();
+    break;
+  case EVENT_TYPE_OP_FINISH:
+    event = OpFinishEvent();
+    break;
+  case EVENT_TYPE_SNAP_CREATE:
+    event = SnapCreateEvent();
+    break;
+  case EVENT_TYPE_SNAP_REMOVE:
+    event = SnapRemoveEvent();
+    break;
+  case EVENT_TYPE_SNAP_RENAME:
+    event = SnapRenameEvent();
+    break;
+  case EVENT_TYPE_SNAP_PROTECT:
+    event = SnapProtectEvent();
+    break;
+  case EVENT_TYPE_SNAP_UNPROTECT:
+    event = SnapUnprotectEvent();
+    break;
+  case EVENT_TYPE_SNAP_ROLLBACK:
+    event = SnapRollbackEvent();
+    break;
+  case EVENT_TYPE_RENAME:
+    event = RenameEvent();
+    break;
+  case EVENT_TYPE_RESIZE:
+    event = ResizeEvent();
+    break;
+  case EVENT_TYPE_FLATTEN:
+    event = FlattenEvent();
+    break;
+  default:
+    event = UnknownEvent();
+    break;
+  }
+
+  boost::apply_visitor(DecodeEventVisitor(struct_v, it), event);
+  DECODE_FINISH(it);
+}
+
+void EventEntry::dump(Formatter *f) const {
+  boost::apply_visitor(DumpEventVisitor(f), event);
+}
+
+void EventEntry::generate_test_instances(std::list<EventEntry *> &o) {
+  o.push_back(new EventEntry(AioDiscardEvent()));
+  o.push_back(new EventEntry(AioDiscardEvent(123, 345)));
+
+  bufferlist bl;
+  bl.append(std::string(32, '1'));
+  o.push_back(new EventEntry(AioWriteEvent()));
+  o.push_back(new EventEntry(AioWriteEvent(123, 456, bl)));
+
+  o.push_back(new EventEntry(AioFlushEvent()));
+
+  o.push_back(new EventEntry(OpFinishEvent(123, -1)));
+
+  o.push_back(new EventEntry(SnapCreateEvent()));
+  o.push_back(new EventEntry(SnapCreateEvent(234, "snap")));
+
+  o.push_back(new EventEntry(SnapRemoveEvent()));
+  o.push_back(new EventEntry(SnapRemoveEvent(345, "snap")));
+
+  o.push_back(new EventEntry(SnapRenameEvent()));
+  o.push_back(new EventEntry(SnapRenameEvent(345, 1, "snap")));
+
+  o.push_back(new EventEntry(SnapProtectEvent()));
+  o.push_back(new EventEntry(SnapProtectEvent(456, "snap")));
+
+  o.push_back(new EventEntry(SnapUnprotectEvent()));
+  o.push_back(new EventEntry(SnapUnprotectEvent(567, "snap")));
+
+  o.push_back(new EventEntry(SnapRollbackEvent()));
+  o.push_back(new EventEntry(SnapRollbackEvent(678, "snap")));
+
+  o.push_back(new EventEntry(RenameEvent()));
+  o.push_back(new EventEntry(RenameEvent(789, "image name")));
+
+  o.push_back(new EventEntry(ResizeEvent()));
+  o.push_back(new EventEntry(ResizeEvent(890, 1234)));
+
+  o.push_back(new EventEntry(FlattenEvent(901)));
+}
+
+} // namespace journal
+} // namespace librbd
+
+std::ostream &operator<<(std::ostream &out,
+                         const librbd::journal::EventType &type) {
+  using namespace librbd::journal;
+
+  switch (type) {
+  case EVENT_TYPE_AIO_DISCARD:
+    out << "AioDiscard";
+    break;
+  case EVENT_TYPE_AIO_WRITE:
+    out << "AioWrite";
+    break;
+  case EVENT_TYPE_AIO_FLUSH:
+    out << "AioFlush";
+    break;
+  case EVENT_TYPE_OP_FINISH:
+    out << "OpFinish";
+    break;
+  case EVENT_TYPE_SNAP_CREATE:
+    out << "SnapCreate";
+    break;
+  case EVENT_TYPE_SNAP_REMOVE:
+    out << "SnapRemove";
+    break;
+  case EVENT_TYPE_SNAP_RENAME:
+    out << "SnapRename";
+    break;
+  case EVENT_TYPE_SNAP_PROTECT:
+    out << "SnapProtect";
+    break;
+  case EVENT_TYPE_SNAP_UNPROTECT:
+    out << "SnapUnprotect";
+    break;
+  case EVENT_TYPE_SNAP_ROLLBACK:
+    out << "SnapRollback";
+    break;
+  case EVENT_TYPE_RENAME:
+    out << "Rename";
+    break;
+  case EVENT_TYPE_RESIZE:
+    out << "Resize";
+    break;
+  case EVENT_TYPE_FLATTEN:
+    out << "Flatten";
+    break;
+  default:
+    out << "Unknown (" << static_cast<uint32_t>(type) << ")";
+    break;
+  }
+  return out;
+}
diff --git a/src/librbd/journal/Entries.h b/src/librbd/journal/Entries.h
new file mode 100644 (file)
index 0000000..089644e
--- /dev/null
@@ -0,0 +1,284 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_JOURNAL_ENTRIES_H
+#define CEPH_LIBRBD_JOURNAL_ENTRIES_H
+
+#include "include/int_types.h"
+#include "include/buffer.h"
+#include "include/encoding.h"
+#include "include/types.h"
+#include <iosfwd>
+#include <boost/variant.hpp>
+
+namespace ceph {
+class Formatter;
+}
+
+namespace librbd {
+namespace journal {
+
+enum EventType {
+  EVENT_TYPE_AIO_DISCARD    = 0,
+  EVENT_TYPE_AIO_WRITE      = 1,
+  EVENT_TYPE_AIO_FLUSH      = 2,
+  EVENT_TYPE_OP_FINISH      = 3,
+  EVENT_TYPE_SNAP_CREATE    = 4,
+  EVENT_TYPE_SNAP_REMOVE    = 5,
+  EVENT_TYPE_SNAP_RENAME    = 6,
+  EVENT_TYPE_SNAP_PROTECT   = 7,
+  EVENT_TYPE_SNAP_UNPROTECT = 8,
+  EVENT_TYPE_SNAP_ROLLBACK  = 9,
+  EVENT_TYPE_RENAME         = 10,
+  EVENT_TYPE_RESIZE         = 11,
+  EVENT_TYPE_FLATTEN        = 12
+};
+
+struct AioDiscardEvent {
+  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_DISCARD;
+
+  uint64_t offset;
+  size_t length;
+
+  AioDiscardEvent() : offset(0), length(0) {
+  }
+  AioDiscardEvent(uint64_t _offset, size_t _length)
+    : offset(_offset), length(_length) {
+  }
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
+struct AioWriteEvent {
+  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_WRITE;
+
+  uint64_t offset;
+  size_t length;
+  bufferlist data;
+
+  AioWriteEvent() : offset(0), length(0) {
+  }
+  AioWriteEvent(uint64_t _offset, size_t _length, const bufferlist &_data)
+    : offset(_offset), length(_length), data(_data) {
+  }
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
+struct AioFlushEvent {
+  static const EventType EVENT_TYPE = EVENT_TYPE_AIO_FLUSH;
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
+struct OpEventBase {
+  uint64_t tid;
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(__u8 version, bufferlist::iterator& it);
+  virtual void dump(Formatter *f) const;
+
+protected:
+  OpEventBase() : tid(0) {
+  }
+  OpEventBase(uint64_t _tid) : tid(_tid) {
+  }
+  virtual ~OpEventBase() {}
+};
+
+struct OpStartEventBase : public OpEventBase {
+protected:
+  OpStartEventBase() {
+  }
+  OpStartEventBase(uint64_t tid) : OpEventBase(tid) {
+  }
+};
+
+struct OpFinishEvent : public OpEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_OP_FINISH;
+
+  int r;
+
+  OpFinishEvent() : r(0) {
+  }
+  OpFinishEvent(uint64_t tid, int _r) : OpEventBase(tid), r(_r) {
+  }
+};
+
+struct SnapEventBase : public OpStartEventBase {
+  std::string snap_name;
+
+  SnapEventBase() {
+  }
+  SnapEventBase(uint64_t tid, const std::string &_snap_name)
+    : OpStartEventBase(tid), snap_name(_snap_name) {
+  }
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(__u8 version, bufferlist::iterator& it);
+  virtual void dump(Formatter *f) const;
+};
+
+struct SnapCreateEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_CREATE;
+
+  SnapCreateEvent() {
+  }
+  SnapCreateEvent(uint64_t tid, const std::string &snap_name)
+    : SnapEventBase(tid, snap_name) {
+  }
+};
+
+struct SnapRemoveEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_REMOVE;
+
+  SnapRemoveEvent() {
+  }
+  SnapRemoveEvent(uint64_t tid, const std::string &snap_name)
+    : SnapEventBase(tid, snap_name) {
+  }
+};
+
+struct SnapRenameEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_RENAME;
+
+  uint64_t snap_id;
+
+  SnapRenameEvent() : snap_id(CEPH_NOSNAP) {
+  }
+  SnapRenameEvent(uint64_t tid, uint64_t src_snap_id,
+                  const std::string &dest_snap_name)
+    : SnapEventBase(tid, dest_snap_name), snap_id(src_snap_id) {
+  }
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(__u8 version, bufferlist::iterator& it);
+  virtual void dump(Formatter *f) const;
+};
+
+struct SnapProtectEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_PROTECT;
+
+  SnapProtectEvent() {
+  }
+  SnapProtectEvent(uint64_t tid, const std::string &snap_name)
+    : SnapEventBase(tid, snap_name) {
+  }
+};
+
+struct SnapUnprotectEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_UNPROTECT;
+
+  SnapUnprotectEvent() {
+  }
+  SnapUnprotectEvent(uint64_t tid, const std::string &snap_name)
+    : SnapEventBase(tid, snap_name) {
+  }
+};
+
+struct SnapRollbackEvent : public SnapEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_SNAP_ROLLBACK;
+
+  SnapRollbackEvent() {
+  }
+  SnapRollbackEvent(uint64_t tid, const std::string &snap_name)
+    : SnapEventBase(tid, snap_name) {
+  }
+};
+
+struct RenameEvent : public OpStartEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_RENAME;
+
+  std::string image_name;
+
+  RenameEvent() {
+  }
+  RenameEvent(uint64_t tid, const std::string &_image_name)
+    : OpStartEventBase(tid), image_name(_image_name) {
+  }
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(__u8 version, bufferlist::iterator& it);
+  virtual void dump(Formatter *f) const;
+};
+
+struct ResizeEvent : public OpStartEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_RESIZE;
+
+  uint64_t size;
+
+  ResizeEvent() : size(0) {
+  }
+  ResizeEvent(uint64_t tid, uint64_t _size)
+    : OpStartEventBase(tid), size(_size) {
+  }
+
+  virtual void encode(bufferlist& bl) const;
+  virtual void decode(__u8 version, bufferlist::iterator& it);
+  virtual void dump(Formatter *f) const;
+};
+
+struct FlattenEvent : public OpStartEventBase {
+  static const EventType EVENT_TYPE = EVENT_TYPE_FLATTEN;
+
+  FlattenEvent() {
+  }
+  FlattenEvent(uint64_t tid) : OpStartEventBase(tid) {
+  }
+};
+
+struct UnknownEvent {
+  static const EventType EVENT_TYPE = static_cast<EventType>(-1);
+
+  void encode(bufferlist& bl) const;
+  void decode(__u8 version, bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+};
+
+typedef boost::variant<AioDiscardEvent,
+                       AioWriteEvent,
+                       AioFlushEvent,
+                       OpFinishEvent,
+                       SnapCreateEvent,
+                       SnapRemoveEvent,
+                       SnapRenameEvent,
+                       SnapProtectEvent,
+                       SnapUnprotectEvent,
+                       SnapRollbackEvent,
+                       RenameEvent,
+                       ResizeEvent,
+                       FlattenEvent,
+                       UnknownEvent> Event;
+
+struct EventEntry {
+  EventEntry() : event(UnknownEvent()) {
+  }
+  EventEntry(const Event &_event) : event(_event) {
+  }
+
+  Event event;
+
+  EventType get_event_type() const;
+
+  void encode(bufferlist& bl) const;
+  void decode(bufferlist::iterator& it);
+  void dump(Formatter *f) const;
+
+  static void generate_test_instances(std::list<EventEntry *> &o);
+};
+
+} // namespace journal
+} // namespace librbd
+
+std::ostream &operator<<(std::ostream &out,
+                         const librbd::journal::EventType &type);
+
+WRITE_CLASS_ENCODER(librbd::journal::EventEntry);
+
+#endif // CEPH_LIBRBD_JOURNAL_ENTRIES_H
diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc
new file mode 100644 (file)
index 0000000..8cc5375
--- /dev/null
@@ -0,0 +1,194 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/journal/Replay.h"
+#include "librbd/AioCompletion.h"
+#include "librbd/AioImageRequest.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/internal.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::journal::Replay: "
+
+namespace librbd {
+namespace journal {
+
+Replay::Replay(ImageCtx &image_ctx)
+  : m_image_ctx(image_ctx), m_lock("Replay::m_lock"), m_ret_val(0) {
+}
+
+Replay::~Replay() {
+  assert(m_aio_completions.empty());
+}
+
+int Replay::process(bufferlist::iterator it, Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << dendl;
+
+  RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
+  journal::EventEntry event_entry;
+  try {
+    ::decode(event_entry, it);
+  } catch (const buffer::error &err) {
+    lderr(cct) << "failed to decode event entry: " << err.what() << dendl;
+    return -EINVAL;
+  }
+
+  boost::apply_visitor(EventVisitor(this, on_safe), event_entry.event);
+  return 0;
+}
+
+int Replay::flush() {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << dendl;
+
+  Mutex::Locker locker(m_lock);
+  while (!m_aio_completions.empty()) {
+    m_cond.Wait(m_lock);
+  }
+  return m_ret_val;
+}
+
+void Replay::handle_event(const journal::AioDiscardEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": AIO discard event" << dendl;
+
+  AioCompletion *aio_comp = create_aio_completion(on_safe);
+  AioImageRequest::aio_discard(&m_image_ctx, aio_comp, event.offset,
+                               event.length);
+}
+
+void Replay::handle_event(const journal::AioWriteEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": AIO write event" << dendl;
+
+  bufferlist data = event.data;
+  AioCompletion *aio_comp = create_aio_completion(on_safe);
+  AioImageRequest::aio_write(&m_image_ctx, aio_comp, event.offset, event.length,
+                             data.c_str(), 0);
+}
+
+void Replay::handle_event(const journal::AioFlushEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": AIO flush event" << dendl;
+
+  AioCompletion *aio_comp = create_aio_completion(on_safe);
+  AioImageRequest::aio_flush(&m_image_ctx, aio_comp);
+}
+
+  void Replay::handle_event(const journal::OpFinishEvent &event,
+                                  Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Op finish event" << dendl;
+}
+
+void Replay::handle_event(const journal::SnapCreateEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap create event" << dendl;
+}
+
+void Replay::handle_event(const journal::SnapRemoveEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap remove event" << dendl;
+}
+
+void Replay::handle_event(const journal::SnapRenameEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap rename event" << dendl;
+}
+
+void Replay::handle_event(const journal::SnapProtectEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap protect event" << dendl;
+}
+
+void Replay::handle_event(const journal::SnapUnprotectEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap unprotect event"
+                 << dendl;
+}
+
+void Replay::handle_event(const journal::SnapRollbackEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Snap rollback start event"
+                 << dendl;
+}
+
+void Replay::handle_event(const journal::RenameEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Rename event" << dendl;
+}
+
+void Replay::handle_event(const journal::ResizeEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Resize start event" << dendl;
+}
+
+void Replay::handle_event(const journal::FlattenEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": Flatten start event" << dendl;
+}
+
+void Replay::handle_event(const journal::UnknownEvent &event,
+                                Context *on_safe) {
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": unknown event" << dendl;
+  on_safe->complete(0);
+}
+
+AioCompletion *Replay::create_aio_completion(Context *on_safe) {
+  Mutex::Locker locker(m_lock);
+  AioCompletion *aio_comp = AioCompletion::create(this, aio_completion_callback,
+                                                  nullptr);
+  m_aio_completions.insert(std::pair<AioCompletion*,Context*>(
+                            aio_comp, on_safe));
+  return aio_comp;
+}
+
+void Replay::handle_aio_completion(AioCompletion *aio_comp) {
+  Mutex::Locker locker(m_lock);
+
+  AioCompletions::iterator it = m_aio_completions.find(aio_comp);
+  assert(it != m_aio_completions.end());
+
+  int r = aio_comp->get_return_value();
+
+  CephContext *cct = m_image_ctx.cct;
+  ldout(cct, 20) << this << " " << __func__ << ": aio_comp=" << aio_comp << ", "
+                 << "r=" << r << dendl;
+
+  Context *on_safe = it->second;
+  on_safe->complete(r);
+
+  if (r < 0 && m_ret_val == 0) {
+    m_ret_val = r;
+  }
+
+  m_aio_completions.erase(it);
+  if (m_aio_completions.empty())
+    m_cond.Signal();
+}
+
+void Replay::aio_completion_callback(completion_t cb, void *arg) {
+  Replay *replay = reinterpret_cast<Replay *>(arg);
+  AioCompletion *aio_comp = reinterpret_cast<AioCompletion *>(cb);
+
+  replay->handle_aio_completion(aio_comp);
+  aio_comp->release();
+}
+
+} // namespace journal
+} // namespace librbd
diff --git a/src/librbd/journal/Replay.h b/src/librbd/journal/Replay.h
new file mode 100644 (file)
index 0000000..dc82745
--- /dev/null
@@ -0,0 +1,80 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_JOURNAL_REPLAY_H
+#define CEPH_LIBRBD_JOURNAL_REPLAY_H
+
+#include "include/int_types.h"
+#include "include/buffer_fwd.h"
+#include "include/rbd/librbd.hpp"
+#include "common/Cond.h"
+#include "common/Mutex.h"
+#include "librbd/journal/Entries.h"
+#include <boost/variant.hpp>
+#include <map>
+
+namespace librbd {
+
+class AioCompletion;
+class ImageCtx;
+
+namespace journal {
+
+class Replay {
+public:
+  Replay(ImageCtx &image_ctx);
+  ~Replay();
+
+  int process(bufferlist::iterator it, Context *on_safe = NULL);
+  int flush();
+
+private:
+  typedef std::map<AioCompletion*,Context*> AioCompletions;
+
+  struct EventVisitor : public boost::static_visitor<void> {
+    Replay *replay;
+    Context *on_safe;
+
+    EventVisitor(Replay *_replay, Context *_on_safe)
+      : replay(_replay), on_safe(_on_safe) {
+    }
+
+    template <typename Event>
+    inline void operator()(const Event &event) const {
+      replay->handle_event(event, on_safe);
+    }
+  };
+
+  ImageCtx &m_image_ctx;
+
+  Mutex m_lock;
+  Cond m_cond;
+
+  AioCompletions m_aio_completions;
+  int m_ret_val;
+
+  void handle_event(const AioDiscardEvent &event, Context *on_safe);
+  void handle_event(const AioWriteEvent &event, Context *on_safe);
+  void handle_event(const AioFlushEvent &event, Context *on_safe);
+  void handle_event(const OpFinishEvent &event, Context *on_safe);
+  void handle_event(const SnapCreateEvent &event, Context *on_safe);
+  void handle_event(const SnapRemoveEvent &event, Context *on_safe);
+  void handle_event(const SnapRenameEvent &event, Context *on_safe);
+  void handle_event(const SnapProtectEvent &event, Context *on_safe);
+  void handle_event(const SnapUnprotectEvent &event, Context *on_safe);
+  void handle_event(const SnapRollbackEvent &event, Context *on_safe);
+  void handle_event(const RenameEvent &event, Context *on_safe);
+  void handle_event(const ResizeEvent &event, Context *on_safe);
+  void handle_event(const FlattenEvent &event, Context *on_safe);
+  void handle_event(const UnknownEvent &event, Context *on_safe);
+
+  AioCompletion *create_aio_completion(Context *on_safe);
+  void handle_aio_completion(AioCompletion *aio_comp);
+
+  static void aio_completion_callback(completion_t cb, void *arg);
+};
+
+} // namespace journal
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_JOURNAL_REPLAY_H
index c0dd3cbbcadb308ee5db1e19869ca7d93855ac4e..68b22db746e85553963b564016d0515f5cd4b359 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "librbd/AsyncRequest.h"
 #include "include/Context.h"
-#include "librbd/JournalTypes.h"
+#include "librbd/journal/Entries.h"
 
 namespace librbd {
 
index 4458654285d71263927cd7c98d4a14c14529817c..b8f7575359b61dd6f705cbaffb9dcadd6e9834f1 100644 (file)
@@ -344,9 +344,9 @@ librbd_test_la_SOURCES = \
        test/librbd/test_librbd.cc \
        test/librbd/test_ImageWatcher.cc \
        test/librbd/test_internal.cc \
-       test/librbd/test_JournalEntries.cc \
-       test/librbd/test_JournalReplay.cc \
-       test/librbd/test_ObjectMap.cc
+       test/librbd/test_ObjectMap.cc \
+       test/librbd/journal/test_Entries.cc \
+       test/librbd/journal/test_Replay.cc
 librbd_test_la_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 noinst_LTLIBRARIES += librbd_test.la
 
index add2a0d680d4d82c9341e80944af363c5b41fc93..e63dc8de8cf5137e154037aae5fea1a43788ef51 100644 (file)
@@ -236,7 +236,7 @@ TYPE(ETableServer)
 TYPE(EUpdate)
 
 #ifdef WITH_RBD
-#include "librbd/JournalTypes.h"
+#include "librbd/journal/Entries.h"
 TYPE(librbd::journal::EventEntry)
 #include "librbd/WatchNotifyTypes.h"
 TYPE(librbd::watch_notify::NotifyMessage)
diff --git a/src/test/librbd/journal/test_Entries.cc b/src/test/librbd/journal/test_Entries.cc
new file mode 100644 (file)
index 0000000..d651d6f
--- /dev/null
@@ -0,0 +1,214 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/librbd/test_fixture.h"
+#include "test/librbd/test_support.h"
+#include "librbd/AioCompletion.h"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/internal.h"
+#include "librbd/Journal.h"
+#include "librbd/journal/Entries.h"
+#include "journal/Journaler.h"
+#include "journal/ReplayEntry.h"
+#include "journal/ReplayHandler.h"
+#include <list>
+#include <boost/variant.hpp>
+
+void register_test_journal_entries() {
+}
+
+class TestJournalEntries : public TestFixture {
+public:
+  typedef std::list<journal::Journaler *> Journalers;
+
+  struct ReplayHandler : public journal::ReplayHandler {
+    Mutex lock;
+    Cond cond;
+    bool entries_available;
+    bool complete;
+
+    ReplayHandler()
+      : lock("ReplayHandler::lock"), entries_available(false), complete(false) {
+    }
+
+    virtual void get() {
+    }
+    virtual void put() {
+    }
+
+    virtual void handle_entries_available()  {
+      Mutex::Locker locker(lock);
+      entries_available = true;
+      cond.Signal();
+    }
+
+    virtual void handle_complete(int r) {
+      Mutex::Locker locker(lock);
+      complete = true;
+      cond.Signal();
+    }
+  };
+
+  ReplayHandler m_replay_handler;
+  Journalers m_journalers;
+
+  virtual void TearDown() {
+    for (Journalers::iterator it = m_journalers.begin();
+         it != m_journalers.end(); ++it) {
+      journal::Journaler *journaler = *it;
+      journaler->stop_replay();
+      delete journaler;
+    }
+
+    TestFixture::TearDown();
+  }
+
+  journal::Journaler *create_journaler(librbd::ImageCtx *ictx) {
+    journal::Journaler *journaler = new journal::Journaler(
+      ictx->md_ctx, ictx->id, "dummy client", 1);
+
+    int r = journaler->register_client("unit test client");
+    if (r < 0) {
+      ADD_FAILURE() << "failed to register journal client";
+      delete journaler;
+      return NULL;
+    }
+
+    C_SaferCond cond;
+    journaler->init(&cond);
+    r = cond.wait();
+    if (r < 0) {
+      ADD_FAILURE() << "failed to initialize journal client";
+      delete journaler;
+      return NULL;
+    }
+
+    journaler->start_live_replay(&m_replay_handler, 0.1);
+    m_journalers.push_back(journaler);
+    return journaler;
+  }
+
+  bool wait_for_entries_available(librbd::ImageCtx *ictx) {
+    Mutex::Locker locker(m_replay_handler.lock);
+    while (!m_replay_handler.entries_available) {
+      if (m_replay_handler.cond.WaitInterval(ictx->cct, m_replay_handler.lock,
+                                             utime_t(10, 0)) != 0) {
+        return false;
+      }
+    }
+    m_replay_handler.entries_available = false;
+    return true;
+  }
+
+  bool get_event_entry(const journal::ReplayEntry &replay_entry,
+                       librbd::journal::EventEntry *event_entry) {
+    try {
+      bufferlist data_bl = replay_entry.get_data();
+      bufferlist::iterator it = data_bl.begin();
+      ::decode(*event_entry, it);
+    } catch (const buffer::error &err) {
+      return false;
+    }
+    return true;
+  }
+
+};
+
+TEST_F(TestJournalEntries, AioWrite) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  journal::Journaler *journaler = create_journaler(ictx);
+  ASSERT_TRUE(journaler != NULL);
+
+  std::string buffer(512, '1');
+  C_SaferCond cond_ctx;
+  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
+  c->get();
+  ictx->aio_work_queue->aio_write(c, 123, buffer.size(), buffer.c_str(), 0);
+  ASSERT_EQ(0, c->wait_for_complete());
+  c->put();
+
+  ASSERT_TRUE(wait_for_entries_available(ictx));
+
+  journal::ReplayEntry replay_entry;
+  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
+
+  librbd::journal::EventEntry event_entry;
+  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
+
+  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_WRITE,
+            event_entry.get_event_type());
+
+  librbd::journal::AioWriteEvent aio_write_event =
+    boost::get<librbd::journal::AioWriteEvent>(event_entry.event);
+  ASSERT_EQ(123U, aio_write_event.offset);
+  ASSERT_EQ(buffer.size(), aio_write_event.length);
+
+  bufferlist buffer_bl;
+  buffer_bl.append(buffer);
+  ASSERT_TRUE(aio_write_event.data.contents_equal(buffer_bl));
+}
+
+TEST_F(TestJournalEntries, AioDiscard) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  journal::Journaler *journaler = create_journaler(ictx);
+  ASSERT_TRUE(journaler != NULL);
+
+  C_SaferCond cond_ctx;
+  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
+  c->get();
+  ictx->aio_work_queue->aio_discard(c, 123, 234);
+  ASSERT_EQ(0, c->wait_for_complete());
+  c->put();
+
+  ASSERT_TRUE(wait_for_entries_available(ictx));
+
+  journal::ReplayEntry replay_entry;
+  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
+
+  librbd::journal::EventEntry event_entry;
+  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
+
+  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_DISCARD,
+            event_entry.get_event_type());
+
+  librbd::journal::AioDiscardEvent aio_discard_event =
+    boost::get<librbd::journal::AioDiscardEvent>(event_entry.event);
+  ASSERT_EQ(123U, aio_discard_event.offset);
+  ASSERT_EQ(234U, aio_discard_event.length);
+}
+
+TEST_F(TestJournalEntries, AioFlush) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+  journal::Journaler *journaler = create_journaler(ictx);
+  ASSERT_TRUE(journaler != NULL);
+
+  C_SaferCond cond_ctx;
+  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
+  c->get();
+  ictx->aio_work_queue->aio_flush(c);
+  ASSERT_EQ(0, c->wait_for_complete());
+  c->put();
+
+  ASSERT_TRUE(wait_for_entries_available(ictx));
+
+  journal::ReplayEntry replay_entry;
+  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
+
+  librbd::journal::EventEntry event_entry;
+  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
+
+  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_FLUSH,
+            event_entry.get_event_type());
+}
diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc
new file mode 100644 (file)
index 0000000..ab8d54e
--- /dev/null
@@ -0,0 +1,162 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/librbd/test_fixture.h"
+#include "test/librbd/test_support.h"
+#include "librbd/AioCompletion.h"
+#include "librbd/AioImageRequest.h"
+#include "librbd/AioImageRequestWQ.h"
+#include "librbd/ExclusiveLock.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/ImageWatcher.h"
+#include "librbd/Journal.h"
+#include "librbd/journal/Entries.h"
+
+void register_test_journal_replay() {
+}
+
+class TestJournalReplay : public TestFixture {
+public:
+
+  int when_acquired_lock(librbd::ImageCtx *ictx) {
+    C_SaferCond lock_ctx;
+    {
+      RWLock::WLocker owner_locker(ictx->owner_lock);
+      ictx->exclusive_lock->request_lock(&lock_ctx);
+    }
+    return lock_ctx.wait();
+  }
+};
+
+TEST_F(TestJournalReplay, AioDiscardEvent) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  // write to the image w/o using the journal
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ictx->features &= ~RBD_FEATURE_JOURNALING;
+
+  std::string payload(4096, '1');
+  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_write(aio_comp, 0, payload.size(), payload.c_str(),
+                                  0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_flush(aio_comp);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  std::string read_payload(4096, '\0');
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
+                                 &read_payload[0], NULL, 0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+  ASSERT_EQ(payload, read_payload);
+  close_image(ictx);
+
+  // inject a discard operation into the journal
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  librbd::journal::EventEntry event_entry(
+    librbd::journal::AioDiscardEvent(0, payload.size()));
+  librbd::Journal::AioObjectRequests requests;
+  {
+    RWLock::RLocker owner_locker(ictx->owner_lock);
+    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
+  }
+
+  // re-open the journal so that it replays the new entry
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
+                                 &read_payload[0], NULL, 0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+  ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload);
+}
+
+TEST_F(TestJournalReplay, AioWriteEvent) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  // inject a write operation into the journal
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  std::string payload(4096, '1');
+  bufferlist payload_bl;
+  payload_bl.append(payload);
+  librbd::journal::EventEntry event_entry(
+    librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
+  librbd::Journal::AioObjectRequests requests;
+  {
+    RWLock::RLocker owner_locker(ictx->owner_lock);
+    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
+  }
+
+  // re-open the journal so that it replays the new entry
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  std::string read_payload(4096, '\0');
+  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
+                                 &read_payload[0], NULL, 0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+  ASSERT_EQ(payload, read_payload);
+}
+
+TEST_F(TestJournalReplay, AioFlushEvent) {
+  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
+
+  // inject a flush operation into the journal
+  librbd::ImageCtx *ictx;
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  librbd::journal::AioFlushEvent aio_flush_event;
+  librbd::journal::EventEntry event_entry(aio_flush_event);
+  librbd::Journal::AioObjectRequests requests;
+  {
+    RWLock::RLocker owner_locker(ictx->owner_lock);
+    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
+  }
+
+  // start an AIO write op
+  librbd::Journal *journal = ictx->journal;
+  ictx->journal = NULL;
+
+  std::string payload(m_image_size, '1');
+  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
+  {
+    RWLock::RLocker owner_lock(ictx->owner_lock);
+    librbd::AioImageRequest::aio_write(ictx, aio_comp, 0, payload.size(),
+                                       payload.c_str(), 0);
+  }
+  ictx->journal = journal;
+
+  // re-open the journal so that it replays the new entry
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, when_acquired_lock(ictx));
+
+  ASSERT_TRUE(aio_comp->is_complete());
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+
+  std::string read_payload(m_image_size, '\0');
+  aio_comp = new librbd::AioCompletion();
+  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
+                                 &read_payload[0], NULL, 0);
+  ASSERT_EQ(0, aio_comp->wait_for_complete());
+  aio_comp->release();
+  ASSERT_EQ(payload, read_payload);
+}
+
index e0c8d1f719aeffa3939d147cb4c614c99c9fa6cf..f20acd353b43ad062d1285f87f114ecf558963ea 100644 (file)
@@ -5,8 +5,8 @@
 #define CEPH_TEST_LIBRBD_MOCK_JOURNAL_H
 
 #include "gmock/gmock.h"
-#include "librbd/JournalTypes.h"
 #include "librbd/Journal.h"
+#include "librbd/journal/Entries.h"
 
 namespace librbd {
 
diff --git a/src/test/librbd/test_JournalEntries.cc b/src/test/librbd/test_JournalEntries.cc
deleted file mode 100644 (file)
index 1b8e082..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "test/librbd/test_fixture.h"
-#include "test/librbd/test_support.h"
-#include "librbd/AioCompletion.h"
-#include "librbd/AioImageRequestWQ.h"
-#include "librbd/internal.h"
-#include "librbd/Journal.h"
-#include "librbd/JournalTypes.h"
-#include "journal/Journaler.h"
-#include "journal/ReplayEntry.h"
-#include "journal/ReplayHandler.h"
-#include <list>
-#include <boost/variant.hpp>
-
-void register_test_journal_entries() {
-}
-
-class TestJournalEntries : public TestFixture {
-public:
-  typedef std::list<journal::Journaler *> Journalers;
-
-  struct ReplayHandler : public journal::ReplayHandler {
-    Mutex lock;
-    Cond cond;
-    bool entries_available;
-    bool complete;
-
-    ReplayHandler()
-      : lock("ReplayHandler::lock"), entries_available(false), complete(false) {
-    }
-
-    virtual void get() {
-    }
-    virtual void put() {
-    }
-
-    virtual void handle_entries_available()  {
-      Mutex::Locker locker(lock);
-      entries_available = true;
-      cond.Signal();
-    }
-
-    virtual void handle_complete(int r) {
-      Mutex::Locker locker(lock);
-      complete = true;
-      cond.Signal();
-    }
-  };
-
-  ReplayHandler m_replay_handler;
-  Journalers m_journalers;
-
-  virtual void TearDown() {
-    for (Journalers::iterator it = m_journalers.begin();
-         it != m_journalers.end(); ++it) {
-      journal::Journaler *journaler = *it;
-      journaler->stop_replay();
-      delete journaler;
-    }
-
-    TestFixture::TearDown();
-  }
-
-  journal::Journaler *create_journaler(librbd::ImageCtx *ictx) {
-    journal::Journaler *journaler = new journal::Journaler(
-      ictx->md_ctx, ictx->id, "dummy client", 1);
-
-    int r = journaler->register_client("unit test client");
-    if (r < 0) {
-      ADD_FAILURE() << "failed to register journal client";
-      delete journaler;
-      return NULL;
-    }
-
-    C_SaferCond cond;
-    journaler->init(&cond);
-    r = cond.wait();
-    if (r < 0) {
-      ADD_FAILURE() << "failed to initialize journal client";
-      delete journaler;
-      return NULL;
-    }
-
-    journaler->start_live_replay(&m_replay_handler, 0.1);
-    m_journalers.push_back(journaler);
-    return journaler;
-  }
-
-  bool wait_for_entries_available(librbd::ImageCtx *ictx) {
-    Mutex::Locker locker(m_replay_handler.lock);
-    while (!m_replay_handler.entries_available) {
-      if (m_replay_handler.cond.WaitInterval(ictx->cct, m_replay_handler.lock,
-                                             utime_t(10, 0)) != 0) {
-        return false;
-      }
-    }
-    m_replay_handler.entries_available = false;
-    return true;
-  }
-
-  bool get_event_entry(const journal::ReplayEntry &replay_entry,
-                       librbd::journal::EventEntry *event_entry) {
-    try {
-      bufferlist data_bl = replay_entry.get_data();
-      bufferlist::iterator it = data_bl.begin();
-      ::decode(*event_entry, it);
-    } catch (const buffer::error &err) {
-      return false;
-    }
-    return true;
-  }
-
-};
-
-TEST_F(TestJournalEntries, AioWrite) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
-  journal::Journaler *journaler = create_journaler(ictx);
-  ASSERT_TRUE(journaler != NULL);
-
-  std::string buffer(512, '1');
-  C_SaferCond cond_ctx;
-  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
-  c->get();
-  ictx->aio_work_queue->aio_write(c, 123, buffer.size(), buffer.c_str(), 0);
-  ASSERT_EQ(0, c->wait_for_complete());
-  c->put();
-
-  ASSERT_TRUE(wait_for_entries_available(ictx));
-
-  journal::ReplayEntry replay_entry;
-  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
-
-  librbd::journal::EventEntry event_entry;
-  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
-
-  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_WRITE,
-            event_entry.get_event_type());
-
-  librbd::journal::AioWriteEvent aio_write_event =
-    boost::get<librbd::journal::AioWriteEvent>(event_entry.event);
-  ASSERT_EQ(123U, aio_write_event.offset);
-  ASSERT_EQ(buffer.size(), aio_write_event.length);
-
-  bufferlist buffer_bl;
-  buffer_bl.append(buffer);
-  ASSERT_TRUE(aio_write_event.data.contents_equal(buffer_bl));
-}
-
-TEST_F(TestJournalEntries, AioDiscard) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
-  journal::Journaler *journaler = create_journaler(ictx);
-  ASSERT_TRUE(journaler != NULL);
-
-  C_SaferCond cond_ctx;
-  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
-  c->get();
-  ictx->aio_work_queue->aio_discard(c, 123, 234);
-  ASSERT_EQ(0, c->wait_for_complete());
-  c->put();
-
-  ASSERT_TRUE(wait_for_entries_available(ictx));
-
-  journal::ReplayEntry replay_entry;
-  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
-
-  librbd::journal::EventEntry event_entry;
-  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
-
-  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_DISCARD,
-            event_entry.get_event_type());
-
-  librbd::journal::AioDiscardEvent aio_discard_event =
-    boost::get<librbd::journal::AioDiscardEvent>(event_entry.event);
-  ASSERT_EQ(123U, aio_discard_event.offset);
-  ASSERT_EQ(234U, aio_discard_event.length);
-}
-
-TEST_F(TestJournalEntries, AioFlush) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-
-  journal::Journaler *journaler = create_journaler(ictx);
-  ASSERT_TRUE(journaler != NULL);
-
-  C_SaferCond cond_ctx;
-  librbd::AioCompletion *c = librbd::AioCompletion::create(&cond_ctx);
-  c->get();
-  ictx->aio_work_queue->aio_flush(c);
-  ASSERT_EQ(0, c->wait_for_complete());
-  c->put();
-
-  ASSERT_TRUE(wait_for_entries_available(ictx));
-
-  journal::ReplayEntry replay_entry;
-  ASSERT_TRUE(journaler->try_pop_front(&replay_entry));
-
-  librbd::journal::EventEntry event_entry;
-  ASSERT_TRUE(get_event_entry(replay_entry, &event_entry));
-
-  ASSERT_EQ(librbd::journal::EVENT_TYPE_AIO_FLUSH,
-            event_entry.get_event_type());
-}
diff --git a/src/test/librbd/test_JournalReplay.cc b/src/test/librbd/test_JournalReplay.cc
deleted file mode 100644 (file)
index c5a6ad6..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "test/librbd/test_fixture.h"
-#include "test/librbd/test_support.h"
-#include "librbd/AioCompletion.h"
-#include "librbd/AioImageRequest.h"
-#include "librbd/AioImageRequestWQ.h"
-#include "librbd/ExclusiveLock.h"
-#include "librbd/ImageCtx.h"
-#include "librbd/ImageWatcher.h"
-#include "librbd/Journal.h"
-#include "librbd/JournalTypes.h"
-
-void register_test_journal_replay() {
-}
-
-class TestJournalReplay : public TestFixture {
-public:
-
-  int when_acquired_lock(librbd::ImageCtx *ictx) {
-    C_SaferCond lock_ctx;
-    {
-      RWLock::WLocker owner_locker(ictx->owner_lock);
-      ictx->exclusive_lock->request_lock(&lock_ctx);
-    }
-    return lock_ctx.wait();
-  }
-};
-
-TEST_F(TestJournalReplay, AioDiscardEvent) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  // write to the image w/o using the journal
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ictx->features &= ~RBD_FEATURE_JOURNALING;
-
-  std::string payload(4096, '1');
-  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_write(aio_comp, 0, payload.size(), payload.c_str(),
-                                  0);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-
-  aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_flush(aio_comp);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-
-  std::string read_payload(4096, '\0');
-  aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
-                                 &read_payload[0], NULL, 0);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-  ASSERT_EQ(payload, read_payload);
-  close_image(ictx);
-
-  // inject a discard operation into the journal
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  librbd::journal::EventEntry event_entry(
-    librbd::journal::AioDiscardEvent(0, payload.size()));
-  librbd::Journal::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
-  }
-
-  // re-open the journal so that it replays the new entry
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
-                                 &read_payload[0], NULL, 0);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-  ASSERT_EQ(std::string(read_payload.size(), '\0'), read_payload);
-}
-
-TEST_F(TestJournalReplay, AioWriteEvent) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  // inject a write operation into the journal
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  std::string payload(4096, '1');
-  bufferlist payload_bl;
-  payload_bl.append(payload);
-  librbd::journal::EventEntry event_entry(
-    librbd::journal::AioWriteEvent(0, payload.size(), payload_bl));
-  librbd::Journal::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
-  }
-
-  // re-open the journal so that it replays the new entry
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  std::string read_payload(4096, '\0');
-  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
-                                 &read_payload[0], NULL, 0);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-  ASSERT_EQ(payload, read_payload);
-}
-
-TEST_F(TestJournalReplay, AioFlushEvent) {
-  REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
-
-  // inject a flush operation into the journal
-  librbd::ImageCtx *ictx;
-
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  librbd::journal::AioFlushEvent aio_flush_event;
-  librbd::journal::EventEntry event_entry(aio_flush_event);
-  librbd::Journal::AioObjectRequests requests;
-  {
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    ictx->journal->append_io_event(NULL, event_entry, requests, 0, 0, true);
-  }
-
-  // start an AIO write op
-  librbd::Journal *journal = ictx->journal;
-  ictx->journal = NULL;
-
-  std::string payload(m_image_size, '1');
-  librbd::AioCompletion *aio_comp = new librbd::AioCompletion();
-  {
-    RWLock::RLocker owner_lock(ictx->owner_lock);
-    librbd::AioImageRequest::aio_write(ictx, aio_comp, 0, payload.size(),
-                                       payload.c_str(), 0);
-  }
-  ictx->journal = journal;
-
-  // re-open the journal so that it replays the new entry
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ASSERT_EQ(0, when_acquired_lock(ictx));
-
-  ASSERT_TRUE(aio_comp->is_complete());
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-
-  std::string read_payload(m_image_size, '\0');
-  aio_comp = new librbd::AioCompletion();
-  ictx->aio_work_queue->aio_read(aio_comp, 0, read_payload.size(),
-                                 &read_payload[0], NULL, 0);
-  ASSERT_EQ(0, aio_comp->wait_for_complete());
-  aio_comp->release();
-  ASSERT_EQ(payload, read_payload);
-}
-
index e00665b2425004250fb842075ff8f7e450fd5e89..cd4213aaa3cc03e8ef02ad713cc09682f63d9000 100644 (file)
@@ -21,7 +21,7 @@
 #include "journal/ReplayEntry.h"
 #include "journal/ReplayHandler.h"
 //#include "librbd/Journal.h" // XXXMG: for librbd::Journal::reset()
-#include "librbd/JournalTypes.h"
+#include "librbd/journal/Entries.h"
 
 namespace rbd {
 namespace action {