summaryrefslogtreecommitdiffstats
path: root/src/rbd_replay
diff options
context:
space:
mode:
Diffstat (limited to 'src/rbd_replay')
-rw-r--r--src/rbd_replay/ActionTypes.cc18
-rw-r--r--src/rbd_replay/ActionTypes.h28
-rw-r--r--src/rbd_replay/actions.cc34
-rw-r--r--src/rbd_replay/actions.hpp30
-rw-r--r--src/rbd_replay/ios.cc24
-rw-r--r--src/rbd_replay/ios.hpp50
-rw-r--r--src/rbd_replay/rbd-replay-prep.cc30
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);