]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-replay: async open/close calls support 7259/head
authorMykola Golub <mgolub@mirantis.com>
Wed, 20 Jan 2016 20:28:26 +0000 (22:28 +0200)
committerMykola Golub <mgolub@mirantis.com>
Fri, 22 Jan 2016 09:53:58 +0000 (11:53 +0200)
It still uses sync open/close in replay, which can be improved later.

Signed-off-by: Mykola Golub <mgolub@mirantis.com>
src/rbd_replay/ActionTypes.cc
src/rbd_replay/ActionTypes.h
src/rbd_replay/actions.cc
src/rbd_replay/actions.hpp
src/rbd_replay/ios.cc
src/rbd_replay/ios.hpp
src/rbd_replay/rbd-replay-prep.cc

index 36ed3ca02c72dc01b8b829d1a0aa8184153f73f6..e879384343a944432db7edf91921288e7ede18b5 100644 (file)
@@ -218,6 +218,32 @@ void OpenImageAction::dump(Formatter *f) const {
   f->dump_bool("read_only", read_only);
 }
 
+void AioOpenImageAction::encode(bufferlist &bl) const {
+  ImageActionBase::encode(bl);
+  ::encode(name, bl);
+  ::encode(snap_name, bl);
+  ::encode(read_only, bl);
+}
+
+void AioOpenImageAction::decode(__u8 version, bufferlist::iterator &it) {
+  ImageActionBase::decode(version, it);
+  if (byte_swap_required(version)) {
+    decode_big_endian_string(name, it);
+    decode_big_endian_string(snap_name, it);
+  } else {
+    ::decode(name, it);
+    ::decode(snap_name, it);
+  }
+  ::decode(read_only, it);
+}
+
+void AioOpenImageAction::dump(Formatter *f) const {
+  ImageActionBase::dump(f);
+  f->dump_string("name", name);
+  f->dump_string("snap_name", snap_name);
+  f->dump_bool("read_only", read_only);
+}
+
 void UnknownAction::encode(bufferlist &bl) const {
   assert(false);
 }
@@ -274,6 +300,12 @@ void ActionEntry::decode(__u8 version, bufferlist::iterator &it) {
   case ACTION_TYPE_CLOSE_IMAGE:
     action = CloseImageAction();
     break;
+  case ACTION_TYPE_AIO_OPEN_IMAGE:
+    action = AioOpenImageAction();
+    break;
+  case ACTION_TYPE_AIO_CLOSE_IMAGE:
+    action = AioCloseImageAction();
+    break;
   }
 
   boost::apply_visitor(DecodeVisitor(version, it), action);
@@ -311,6 +343,13 @@ void ActionEntry::generate_test_instances(std::list<ActionEntry *> &o) {
                                               true)));
   o.push_back(new ActionEntry(CloseImageAction()));
   o.push_back(new ActionEntry(CloseImageAction(1, 123456789, dependencies, 3)));
+
+  o.push_back(new ActionEntry(AioOpenImageAction()));
+  o.push_back(new ActionEntry(AioOpenImageAction(1, 123456789, dependencies, 3,
+                                              "image_name", "snap_name",
+                                              true)));
+  o.push_back(new ActionEntry(AioCloseImageAction()));
+  o.push_back(new ActionEntry(AioCloseImageAction(1, 123456789, dependencies, 3)));
 }
 
 } // namespace action
@@ -345,6 +384,12 @@ std::ostream &operator<<(std::ostream &out,
   case ACTION_TYPE_CLOSE_IMAGE:
     out << "CloseImage";
     break;
+  case ACTION_TYPE_AIO_OPEN_IMAGE:
+    out << "AioOpenImage";
+    break;
+  case ACTION_TYPE_AIO_CLOSE_IMAGE:
+    out << "AioCloseImage";
+    break;
   default:
     out << "Unknown (" << static_cast<uint32_t>(type) << ")";
     break;
index fcceca859ceb32c62738bda42479efc6762498d2..302b9e216ff49c721c3868167bf2fd67b6a75c86 100644 (file)
@@ -62,14 +62,16 @@ WRITE_CLASS_ENCODER(Dependency);
 typedef std::vector<Dependency> Dependencies;
 
 enum ActionType {
-  ACTION_TYPE_START_THREAD = 0,
-  ACTION_TYPE_STOP_THREAD  = 1,
-  ACTION_TYPE_READ         = 2,
-  ACTION_TYPE_WRITE        = 3,
-  ACTION_TYPE_AIO_READ     = 4,
-  ACTION_TYPE_AIO_WRITE    = 5,
-  ACTION_TYPE_OPEN_IMAGE   = 6,
-  ACTION_TYPE_CLOSE_IMAGE  = 7
+  ACTION_TYPE_START_THREAD    = 0,
+  ACTION_TYPE_STOP_THREAD     = 1,
+  ACTION_TYPE_READ            = 2,
+  ACTION_TYPE_WRITE           = 3,
+  ACTION_TYPE_AIO_READ        = 4,
+  ACTION_TYPE_AIO_WRITE       = 5,
+  ACTION_TYPE_OPEN_IMAGE      = 6,
+  ACTION_TYPE_CLOSE_IMAGE     = 7,
+  ACTION_TYPE_AIO_OPEN_IMAGE  = 8,
+  ACTION_TYPE_AIO_CLOSE_IMAGE = 9,
 };
 
 struct ActionBase {
@@ -225,6 +227,39 @@ struct CloseImageAction : public ImageActionBase {
   }
 };
 
+struct AioOpenImageAction : public ImageActionBase {
+  static const ActionType ACTION_TYPE = ACTION_TYPE_AIO_OPEN_IMAGE;
+
+  std::string name;
+  std::string snap_name;
+  bool read_only;
+
+  AioOpenImageAction() : read_only(false) {
+  }
+  AioOpenImageAction(action_id_t id, thread_id_t thread_id,
+                    const Dependencies &dependencies, imagectx_id_t imagectx_id,
+                    const std::string &name, const std::string &snap_name,
+                    bool read_only)
+    : ImageActionBase(id, thread_id, dependencies, imagectx_id),
+      name(name), snap_name(snap_name), read_only(read_only) {
+  }
+
+  void encode(bufferlist &bl) const;
+  void decode(__u8 version, bufferlist::iterator &it);
+  void dump(Formatter *f) const;
+};
+
+struct AioCloseImageAction : public ImageActionBase {
+  static const ActionType ACTION_TYPE = ACTION_TYPE_AIO_CLOSE_IMAGE;
+
+  AioCloseImageAction() {
+  }
+  AioCloseImageAction(action_id_t id, thread_id_t thread_id,
+                     const Dependencies &dependencies, imagectx_id_t imagectx_id)
+    : ImageActionBase(id, thread_id, dependencies, imagectx_id) {
+  }
+};
+
 struct UnknownAction {
   static const ActionType ACTION_TYPE = static_cast<ActionType>(-1);
 
@@ -241,6 +276,8 @@ typedef boost::variant<StartThreadAction,
                        AioWriteAction,
                        OpenImageAction,
                        CloseImageAction,
+                       AioOpenImageAction,
+                       AioCloseImageAction,
                        UnknownAction> Action;
 
 class ActionEntry {
index 7726d08706dbc40849d3726c38d23a2886758d4f..33c8de5a38d752d1079d19fcaa168aafffa4cf83 100644 (file)
@@ -65,6 +65,14 @@ struct ConstructVisitor : public boost::static_visitor<Action::ptr> {
     return Action::ptr(new CloseImageAction(action));
   }
 
+  inline Action::ptr operator()(const action::AioOpenImageAction &action) const {
+    return Action::ptr(new AioOpenImageAction(action));
+  }
+
+  inline Action::ptr operator()(const action::AioCloseImageAction &action) const {
+    return Action::ptr(new AioCloseImageAction(action));
+  }
+
   inline Action::ptr operator()(const action::UnknownAction &action) const {
     return Action::ptr();
   }
@@ -175,3 +183,35 @@ void CloseImageAction::perform(ActionCtx &worker) {
   worker.set_action_complete(pending_io_id());
 }
 
+void AioOpenImageAction::perform(ActionCtx &worker) {
+  dout(ACTION_LEVEL) << "Performing " << *this << dendl;
+  // TODO: Make it async
+  PendingIO::ptr io(new PendingIO(pending_io_id(), worker));
+  worker.add_pending(io);
+  librbd::Image *image = new librbd::Image();
+  librbd::RBD *rbd = worker.rbd();
+  rbd_loc name(worker.map_image_name(m_action.name, m_action.snap_name));
+  int r;
+  if (m_action.read_only || worker.readonly()) {
+    r = rbd->open_read_only(*worker.ioctx(), *image, name.image.c_str(), name.snap.c_str());
+  } else {
+    r = rbd->open(*worker.ioctx(), *image, name.image.c_str(), name.snap.c_str());
+  }
+  if (r) {
+    cerr << "Unable to open image '" << m_action.name
+        << "' with snap '" << m_action.snap_name
+        << "' (mapped to '" << name.str()
+        << "') and readonly " << m_action.read_only
+        << ": (" << -r << ") " << strerror(-r) << std::endl;
+    exit(1);
+  }
+  worker.put_image(m_action.imagectx_id, image);
+  worker.remove_pending(io);
+}
+
+void AioCloseImageAction::perform(ActionCtx &worker) {
+  dout(ACTION_LEVEL) << "Performing " << *this << dendl;
+  // TODO: Make it async
+  worker.erase_image(m_action.imagectx_id);
+  worker.set_action_complete(pending_io_id());
+}
index ea46a883362e62ec7badd833d9f2c2bfdade7547..9f0acec90c3e52fb830d3a59e364fc078a313e69 100644 (file)
@@ -280,6 +280,35 @@ protected:
   }
 };
 
+class AioOpenImageAction : public TypedAction<action::AioOpenImageAction> {
+public:
+  AioOpenImageAction(const action::AioOpenImageAction &action)
+    : TypedAction<action::AioOpenImageAction>(action) {
+  }
+
+  virtual void perform(ActionCtx &ctx);
+
+protected:
+  virtual const char *get_action_name() const {
+    return "AioOpenImageAction";
+  }
+};
+
+
+class AioCloseImageAction : public TypedAction<action::AioCloseImageAction> {
+public:
+  AioCloseImageAction(const action::AioCloseImageAction &action)
+    : TypedAction<action::AioCloseImageAction>(action) {
+  }
+
+  virtual void perform(ActionCtx &ctx);
+
+protected:
+  virtual const char *get_action_name() const {
+    return "AioCloseImageAction";
+  }
+};
+
 }
 
 #endif
index 7437bed8897846fc6786e566bfdd90a0ac9d9f59..52d885ac9b5953931e06154af9dba8e5b4a6cd89 100644 (file)
@@ -158,3 +158,27 @@ void CloseImageIO::write_debug(std::ostream& out) const {
   write_debug_base(out, "close image");
   out << ", imagectx=" << m_imagectx;
 }
+
+void AioOpenImageIO::encode(bufferlist &bl) const {
+  action::Action action((action::AioOpenImageAction(
+    ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
+    m_imagectx, m_name, m_snap_name, m_readonly)));
+  ::encode(action, bl);
+}
+
+void AioOpenImageIO::write_debug(std::ostream& out) const {
+  write_debug_base(out, "aio open image");
+  out << ", imagectx=" << m_imagectx << ", name='" << m_name << "', snap_name='" << m_snap_name << "', readonly=" << m_readonly;
+}
+
+void AioCloseImageIO::encode(bufferlist &bl) const {
+  action::Action action((action::AioCloseImageAction(
+    ionum(), thread_id(), convert_dependencies(start_time(), dependencies()),
+    m_imagectx)));
+  ::encode(action, bl);
+}
+
+void AioCloseImageIO::write_debug(std::ostream& out) const {
+  write_debug_base(out, "aio close image");
+  out << ", imagectx=" << m_imagectx;
+}
index 218717b746f70f747be3acf76375291fec6ffd2d..e6c0bf5fd52d418f6c158eb074eed4573e1a3826 100644 (file)
@@ -291,6 +291,61 @@ private:
   imagectx_id_t m_imagectx;
 };
 
+class AioOpenImageIO : public IO {
+public:
+  AioOpenImageIO(action_id_t ionum,
+                uint64_t start_time,
+                thread_id_t thread_id,
+                const io_set_t& deps,
+                imagectx_id_t imagectx,
+                const std::string& name,
+                const std::string& snap_name,
+                bool readonly)
+    : IO(ionum, start_time, thread_id, deps),
+      m_imagectx(imagectx),
+      m_name(name),
+      m_snap_name(snap_name),
+      m_readonly(readonly) {
+  }
+
+  virtual void encode(bufferlist &bl) const;
+
+  imagectx_id_t imagectx() const {
+    return m_imagectx;
+  }
+
+  void write_debug(std::ostream& out) const;
+
+private:
+  imagectx_id_t m_imagectx;
+  std::string m_name;
+  std::string m_snap_name;
+  bool m_readonly;
+};
+
+class AioCloseImageIO : public IO {
+public:
+  AioCloseImageIO(action_id_t ionum,
+                 uint64_t start_time,
+                 thread_id_t thread_id,
+                 const io_set_t& deps,
+                 imagectx_id_t imagectx)
+    : IO(ionum, start_time, thread_id, deps),
+      m_imagectx(imagectx) {
+  }
+
+  virtual void encode(bufferlist &bl) const;
+
+  imagectx_id_t imagectx() const {
+    return m_imagectx;
+  }
+
+  void write_debug(std::ostream& out) const;
+
+private:
+  imagectx_id_t m_imagectx;
+};
+
 }
 
 #endif
index 61cff592cf2759d7dfa49183f468ab821cf89557..647a5e3806319e7ccc36c897716d180aea0bf012 100644 (file)
@@ -372,6 +372,29 @@ private:
       boost::shared_ptr<CloseImageIO> io(boost::dynamic_pointer_cast<CloseImageIO>(thread->latest_io()));
       assert(io);
       m_open_images.erase(io->imagectx());
+    } else if (strcmp(event_name, "librbd:aio_open_image_enter") == 0) {
+      string name(fields.string("name"));
+      string snap_name(fields.string("snap_name"));
+      bool readonly = fields.uint64("read_only");
+      imagectx_id_t imagectx = fields.uint64("imagectx");
+      uint64_t completion = fields.uint64("completion");
+      action_id_t ionum = next_id();
+      pair<string, string> aname(map_image_snap(name, snap_name));
+      IO::ptr io(new AioOpenImageIO(ionum, ts, threadID, m_recent_completions,
+                                   imagectx, aname.first, aname.second,
+                                   readonly));
+      thread->issued_io(io, &m_latest_ios);
+      ios->push_back(io);
+      m_pending_ios[completion] = io;
+    } else if (strcmp(event_name, "librbd:aio_close_image_enter") == 0) {
+      imagectx_id_t imagectx = fields.uint64("imagectx");
+      uint64_t completion = fields.uint64("completion");
+      action_id_t ionum = next_id();
+      IO::ptr io(new AioCloseImageIO(ionum, ts, threadID, m_recent_completions,
+                                    imagectx));
+      thread->issued_io(io, &m_latest_ios);
+      ios->push_back(thread->latest_io());
+      m_pending_ios[completion] = io;
     } else if (strcmp(event_name, "librbd:read_enter") == 0 ||
                strcmp(event_name, "librbd:read2_enter") == 0) {
       string name(fields.string("name"));