diff options
author | Jason Dillaman <dillaman@redhat.com> | 2016-07-18 19:37:37 +0200 |
---|---|---|
committer | Jason Dillaman <dillaman@redhat.com> | 2016-07-19 13:22:28 +0200 |
commit | b7a4db213d0d4812aa6cd9c54e9646ff57d10411 (patch) | |
tree | 5999e64f467cb07cf00d6d54bb8e30fbf2abfc9a /src/rbd_replay | |
parent | Merge pull request #10250 from gregsfortytwo/wip-sessionmap-committing (diff) | |
download | ceph-b7a4db213d0d4812aa6cd9c54e9646ff57d10411.tar.xz ceph-b7a4db213d0d4812aa6cd9c54e9646ff57d10411.zip |
rbd-replay: decode and replay discard IO operations
Fixes: http://tracker.ceph.com/issues/16707
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
Diffstat (limited to 'src/rbd_replay')
-rw-r--r-- | src/rbd_replay/ActionTypes.cc | 18 | ||||
-rw-r--r-- | src/rbd_replay/ActionTypes.h | 28 | ||||
-rw-r--r-- | src/rbd_replay/actions.cc | 34 | ||||
-rw-r--r-- | src/rbd_replay/actions.hpp | 30 | ||||
-rw-r--r-- | src/rbd_replay/ios.cc | 24 | ||||
-rw-r--r-- | src/rbd_replay/ios.hpp | 50 | ||||
-rw-r--r-- | src/rbd_replay/rbd-replay-prep.cc | 30 |
7 files changed, 213 insertions, 1 deletions
diff --git a/src/rbd_replay/ActionTypes.cc b/src/rbd_replay/ActionTypes.cc index dc5388f241e..4e7a297a6c7 100644 --- a/src/rbd_replay/ActionTypes.cc +++ b/src/rbd_replay/ActionTypes.cc @@ -288,12 +288,18 @@ void ActionEntry::decode(__u8 version, bufferlist::iterator &it) { case ACTION_TYPE_WRITE: action = WriteAction(); break; + case ACTION_TYPE_DISCARD: + action = DiscardAction(); + break; case ACTION_TYPE_AIO_READ: action = AioReadAction(); break; case ACTION_TYPE_AIO_WRITE: action = AioWriteAction(); break; + case ACTION_TYPE_AIO_DISCARD: + action = AioDiscardAction(); + break; case ACTION_TYPE_OPEN_IMAGE: action = OpenImageAction(); break; @@ -330,12 +336,18 @@ void ActionEntry::generate_test_instances(std::list<ActionEntry *> &o) { o.push_back(new ActionEntry(WriteAction())); o.push_back(new ActionEntry(WriteAction(1, 123456789, dependencies, 3, 4, 5))); + o.push_back(new ActionEntry(DiscardAction())); + o.push_back(new ActionEntry(DiscardAction(1, 123456789, dependencies, 3, 4, + 5))); o.push_back(new ActionEntry(AioReadAction())); o.push_back(new ActionEntry(AioReadAction(1, 123456789, dependencies, 3, 4, 5))); o.push_back(new ActionEntry(AioWriteAction())); o.push_back(new ActionEntry(AioWriteAction(1, 123456789, dependencies, 3, 4, 5))); + o.push_back(new ActionEntry(AioDiscardAction())); + o.push_back(new ActionEntry(AioDiscardAction(1, 123456789, dependencies, 3, 4, + 5))); o.push_back(new ActionEntry(OpenImageAction())); o.push_back(new ActionEntry(OpenImageAction(1, 123456789, dependencies, 3, @@ -372,12 +384,18 @@ std::ostream &operator<<(std::ostream &out, case ACTION_TYPE_WRITE: out << "Write"; break; + case ACTION_TYPE_DISCARD: + out << "Discard"; + break; case ACTION_TYPE_AIO_READ: out << "AioRead"; break; case ACTION_TYPE_AIO_WRITE: out << "AioWrite"; break; + case ACTION_TYPE_AIO_DISCARD: + out << "AioDiscard"; + break; case ACTION_TYPE_OPEN_IMAGE: out << "OpenImage"; break; diff --git a/src/rbd_replay/ActionTypes.h b/src/rbd_replay/ActionTypes.h index 302b9e216ff..b6dc43351e1 100644 --- a/src/rbd_replay/ActionTypes.h +++ b/src/rbd_replay/ActionTypes.h @@ -72,6 +72,8 @@ enum ActionType { ACTION_TYPE_CLOSE_IMAGE = 7, ACTION_TYPE_AIO_OPEN_IMAGE = 8, ACTION_TYPE_AIO_CLOSE_IMAGE = 9, + ACTION_TYPE_DISCARD = 10, + ACTION_TYPE_AIO_DISCARD = 11 }; struct ActionBase { @@ -170,6 +172,18 @@ struct WriteAction : public IoActionBase { } }; +struct DiscardAction : public IoActionBase { + static const ActionType ACTION_TYPE = ACTION_TYPE_DISCARD; + + DiscardAction() { + } + DiscardAction(action_id_t id, thread_id_t thread_id, + const Dependencies &dependencies, imagectx_id_t imagectx_id, + uint64_t offset, uint64_t length) + : IoActionBase(id, thread_id, dependencies, imagectx_id, offset, length) { + } +}; + struct AioReadAction : public IoActionBase { static const ActionType ACTION_TYPE = ACTION_TYPE_AIO_READ; @@ -194,6 +208,18 @@ struct AioWriteAction : public IoActionBase { } }; +struct AioDiscardAction : public IoActionBase { + static const ActionType ACTION_TYPE = ACTION_TYPE_AIO_DISCARD; + + AioDiscardAction() { + } + AioDiscardAction(action_id_t id, thread_id_t thread_id, + const Dependencies &dependencies, imagectx_id_t imagectx_id, + uint64_t offset, uint64_t length) + : IoActionBase(id, thread_id, dependencies, imagectx_id, offset, length) { + } +}; + struct OpenImageAction : public ImageActionBase { static const ActionType ACTION_TYPE = ACTION_TYPE_OPEN_IMAGE; @@ -272,8 +298,10 @@ typedef boost::variant<StartThreadAction, StopThreadAction, ReadAction, WriteAction, + DiscardAction, AioReadAction, AioWriteAction, + AioDiscardAction, OpenImageAction, CloseImageAction, AioOpenImageAction, diff --git a/src/rbd_replay/actions.cc b/src/rbd_replay/actions.cc index 33c8de5a38d..e596ec0dd50 100644 --- a/src/rbd_replay/actions.cc +++ b/src/rbd_replay/actions.cc @@ -57,6 +57,14 @@ struct ConstructVisitor : public boost::static_visitor<Action::ptr> { return Action::ptr(new AioWriteAction(action)); } + inline Action::ptr operator()(const action::DiscardAction &action) const { + return Action::ptr(new DiscardAction(action)); + } + + inline Action::ptr operator()(const action::AioDiscardAction &action) const { + return Action::ptr(new AioDiscardAction(action)); + } + inline Action::ptr operator()(const action::OpenImageAction &action) const { return Action::ptr(new OpenImageAction(action)); } @@ -118,7 +126,6 @@ void ReadAction::perform(ActionCtx &worker) { worker.remove_pending(io); } - void AioWriteAction::perform(ActionCtx &worker) { static const std::string fake_data(create_fake_data()); dout(ACTION_LEVEL) << "Performing " << *this << dendl; @@ -152,6 +159,31 @@ void WriteAction::perform(ActionCtx &worker) { worker.remove_pending(io); } +void AioDiscardAction::perform(ActionCtx &worker) { + dout(ACTION_LEVEL) << "Performing " << *this << dendl; + librbd::Image *image = worker.get_image(m_action.imagectx_id); + PendingIO::ptr io(new PendingIO(pending_io_id(), worker)); + worker.add_pending(io); + if (worker.readonly()) { + worker.remove_pending(io); + } else { + int r = image->aio_discard(m_action.offset, m_action.length, &io->completion()); + assertf(r >= 0, "id = %d, r = %d", id(), r); + } +} + +void DiscardAction::perform(ActionCtx &worker) { + dout(ACTION_LEVEL) << "Performing " << *this << dendl; + librbd::Image *image = worker.get_image(m_action.imagectx_id); + PendingIO::ptr io(new PendingIO(pending_io_id(), worker)); + worker.add_pending(io); + if (!worker.readonly()) { + ssize_t r = image->discard(m_action.offset, m_action.length); + assertf(r >= 0, "id = %d, r = %d", id(), r); + } + worker.remove_pending(io); +} + void OpenImageAction::perform(ActionCtx &worker) { dout(ACTION_LEVEL) << "Performing " << *this << dendl; PendingIO::ptr io(new PendingIO(pending_io_id(), worker)); diff --git a/src/rbd_replay/actions.hpp b/src/rbd_replay/actions.hpp index eec655a3bd7..df5dde48459 100644 --- a/src/rbd_replay/actions.hpp +++ b/src/rbd_replay/actions.hpp @@ -251,6 +251,36 @@ protected: }; +class AioDiscardAction : public TypedAction<action::AioDiscardAction> { +public: + explicit AioDiscardAction(const action::AioDiscardAction &action) + : TypedAction<action::AioDiscardAction>(action) { + } + + virtual void perform(ActionCtx &ctx); + +protected: + virtual const char *get_action_name() const { + return "AioDiscardAction"; + } +}; + + +class DiscardAction : public TypedAction<action::DiscardAction> { +public: + explicit DiscardAction(const action::DiscardAction &action) + : TypedAction<action::DiscardAction>(action) { + } + + virtual void perform(ActionCtx &ctx); + +protected: + virtual const char *get_action_name() const { + return "DiscardAction"; + } +}; + + class OpenImageAction : public TypedAction<action::OpenImageAction> { public: explicit OpenImageAction(const action::OpenImageAction &action) diff --git a/src/rbd_replay/ios.cc b/src/rbd_replay/ios.cc index f479e0dd9f8..db8470e9cf4 100644 --- a/src/rbd_replay/ios.cc +++ b/src/rbd_replay/ios.cc @@ -111,6 +111,18 @@ void WriteIO::write_debug(std::ostream& out) const { out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]"; } +void DiscardIO::encode(bufferlist &bl) const { + action::Action action((action::DiscardAction( + ionum(), thread_id(), convert_dependencies(start_time(), dependencies()), + m_imagectx, m_offset, m_length))); + ::encode(action, bl); +} + +void DiscardIO::write_debug(std::ostream& out) const { + write_debug_base(out, "discard"); + out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]"; +} + void AioReadIO::encode(bufferlist &bl) const { action::Action action((action::AioReadAction( ionum(), thread_id(), convert_dependencies(start_time(), dependencies()), @@ -135,6 +147,18 @@ void AioWriteIO::write_debug(std::ostream& out) const { out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]"; } +void AioDiscardIO::encode(bufferlist &bl) const { + action::Action action((action::AioDiscardAction( + ionum(), thread_id(), convert_dependencies(start_time(), dependencies()), + m_imagectx, m_offset, m_length))); + ::encode(action, bl); +} + +void AioDiscardIO::write_debug(std::ostream& out) const { + write_debug_base(out, "aio discard"); + out << ", imagectx=" << m_imagectx << ", offset=" << m_offset << ", length=" << m_length << "]"; +} + void OpenImageIO::encode(bufferlist &bl) const { action::Action action((action::OpenImageAction( ionum(), thread_id(), convert_dependencies(start_time(), dependencies()), diff --git a/src/rbd_replay/ios.hpp b/src/rbd_replay/ios.hpp index 7316bc1dcc8..5f19648b9e6 100644 --- a/src/rbd_replay/ios.hpp +++ b/src/rbd_replay/ios.hpp @@ -186,6 +186,31 @@ private: uint64_t m_length; }; +class DiscardIO : public IO { +public: + DiscardIO(action_id_t ionum, + uint64_t start_time, + thread_id_t thread_id, + const io_set_t& deps, + imagectx_id_t imagectx, + uint64_t offset, + uint64_t length) + : IO(ionum, start_time, thread_id, deps), + m_imagectx(imagectx), + m_offset(offset), + m_length(length) { + } + + virtual void encode(bufferlist &bl) const; + + void write_debug(std::ostream& out) const; + +private: + imagectx_id_t m_imagectx; + uint64_t m_offset; + uint64_t m_length; +}; + class AioReadIO : public IO { public: AioReadIO(action_id_t ionum, @@ -236,6 +261,31 @@ private: uint64_t m_length; }; +class AioDiscardIO : public IO { +public: + AioDiscardIO(action_id_t ionum, + uint64_t start_time, + thread_id_t thread_id, + const io_set_t& deps, + imagectx_id_t imagectx, + uint64_t offset, + uint64_t length) + : IO(ionum, start_time, thread_id, deps), + m_imagectx(imagectx), + m_offset(offset), + m_length(length) { + } + + virtual void encode(bufferlist &bl) const; + + void write_debug(std::ostream& out) const; + +private: + imagectx_id_t m_imagectx; + uint64_t m_offset; + uint64_t m_length; +}; + class OpenImageIO : public IO { public: OpenImageIO(action_id_t ionum, diff --git a/src/rbd_replay/rbd-replay-prep.cc b/src/rbd_replay/rbd-replay-prep.cc index c887813a556..1ece6e9bd61 100644 --- a/src/rbd_replay/rbd-replay-prep.cc +++ b/src/rbd_replay/rbd-replay-prep.cc @@ -427,6 +427,21 @@ private: ios->push_back(io); } else if (strcmp(event_name, "librbd:write_exit") == 0) { completed(thread->latest_io()); + } else if (strcmp(event_name, "librbd:discard_enter") == 0) { + string name(fields.string("name")); + string snap_name(fields.string("snap_name")); + bool readonly = fields.int64("read_only"); + uint64_t offset = fields.uint64("off"); + uint64_t length = fields.uint64("len"); + imagectx_id_t imagectx = fields.uint64("imagectx"); + require_image(ts, thread, imagectx, name, snap_name, readonly, ios); + action_id_t ionum = next_id(); + IO::ptr io(new DiscardIO(ionum, ts, threadID, m_recent_completions, + imagectx, offset, length)); + thread->issued_io(io, &m_latest_ios); + ios->push_back(io); + } else if (strcmp(event_name, "librbd:discard_exit") == 0) { + completed(thread->latest_io()); } else if (strcmp(event_name, "librbd:aio_read_enter") == 0 || strcmp(event_name, "librbd:aio_read2_enter") == 0) { string name(fields.string("name")); @@ -459,6 +474,21 @@ private: thread->issued_io(io, &m_latest_ios); ios->push_back(io); m_pending_ios[completion] = io; + } else if (strcmp(event_name, "librbd:aio_discard_enter") == 0) { + string name(fields.string("name")); + string snap_name(fields.string("snap_name")); + bool readonly = fields.int64("read_only"); + uint64_t offset = fields.uint64("off"); + uint64_t length = fields.uint64("len"); + uint64_t completion = fields.uint64("completion"); + imagectx_id_t imagectx = fields.uint64("imagectx"); + require_image(ts, thread, imagectx, name, snap_name, readonly, ios); + action_id_t ionum = next_id(); + IO::ptr io(new AioDiscardIO(ionum, ts, threadID, m_recent_completions, + imagectx, offset, length)); + thread->issued_io(io, &m_latest_ios); + ios->push_back(io); + m_pending_ios[completion] = io; } else if (strcmp(event_name, "librbd:aio_complete_enter") == 0) { uint64_t completion = fields.uint64("completion"); map<uint64_t, IO::ptr>::iterator itr = m_pending_ios.find(completion); |