From 3dc8443c5645854a6f85f4e4320047407d68ab74 Mon Sep 17 00:00:00 2001 From: Adam Crume Date: Mon, 21 Jul 2014 14:38:28 -0700 Subject: [PATCH] rbd-replay: Add --read-only flag Removes ignoreWrites flag in prep-for-replay.py Signed-off-by: Adam Crume --- src/rbd_replay/Replayer.cc | 13 +++++- src/rbd_replay/Replayer.hpp | 7 ++++ src/rbd_replay/actions.cc | 16 +++++--- src/rbd_replay/actions.hpp | 2 + src/rbd_replay/prep-for-replay.py | 66 +++++++++++++++---------------- src/rbd_replay/rbd-replay.cc | 9 ++++- 6 files changed, 70 insertions(+), 43 deletions(-) diff --git a/src/rbd_replay/Replayer.cc b/src/rbd_replay/Replayer.cc index e9ec1260bed16..0d14766830c90 100644 --- a/src/rbd_replay/Replayer.cc +++ b/src/rbd_replay/Replayer.cc @@ -116,11 +116,14 @@ librados::IoCtx* Worker::ioctx() { return m_replayer.get_ioctx(); } - void Worker::set_action_complete(action_id_t id) { m_replayer.set_action_complete(id); } +bool Worker::readonly() const { + return m_replayer.readonly(); +} + Replayer::Replayer(int num_action_trackers) : m_num_action_trackers(num_action_trackers), @@ -278,3 +281,11 @@ void Replayer::clear_images() { void Replayer::set_latency_multiplier(float f) { m_latency_multiplier = f; } + +bool Replayer::readonly() const { + return m_readonly; +} + +void Replayer::set_readonly(bool readonly) { + m_readonly = readonly; +} diff --git a/src/rbd_replay/Replayer.hpp b/src/rbd_replay/Replayer.hpp index d2ae9daf1f552..f88eb55194d26 100644 --- a/src/rbd_replay/Replayer.hpp +++ b/src/rbd_replay/Replayer.hpp @@ -53,6 +53,8 @@ public: void set_action_complete(action_id_t id); + bool readonly() const; + private: void run(); @@ -96,6 +98,10 @@ public: void set_latency_multiplier(float f); + bool readonly() const; + + void set_readonly(bool readonly); + private: struct action_tracker_d { // Maps an action ID to the time the action completed @@ -115,6 +121,7 @@ private: librbd::RBD* m_rbd; librados::IoCtx* m_ioctx; float m_latency_multiplier; + bool m_readonly; std::map m_images; boost::shared_mutex m_images_mutex; diff --git a/src/rbd_replay/actions.cc b/src/rbd_replay/actions.cc index 839787015b8b0..e328e22b9754f 100644 --- a/src/rbd_replay/actions.cc +++ b/src/rbd_replay/actions.cc @@ -238,8 +238,12 @@ void AioWriteAction::perform(ActionCtx &worker) { PendingIO::ptr io(new PendingIO(pending_io_id(), worker)); io->bufferlist().append_zero(m_length); worker.add_pending(io); - int r = image->aio_write(m_offset, m_length, io->bufferlist(), &io->completion()); - assertf(r >= 0, "id = %d, r = %d", id(), r); + if (worker.readonly()) { + worker.remove_pending(io); + } else { + int r = image->aio_write(m_offset, m_length, io->bufferlist(), &io->completion()); + assertf(r >= 0, "id = %d, r = %d", id(), r); + } } std::ostream& AioWriteAction::dump(std::ostream& o) const { @@ -272,8 +276,10 @@ void WriteAction::perform(ActionCtx &worker) { PendingIO::ptr io(new PendingIO(pending_io_id(), worker)); worker.add_pending(io); io->bufferlist().append_zero(m_length); - ssize_t r = image->write(m_offset, m_length, io->bufferlist()); - assertf(r >= 0, "id = %d, r = %d", id(), r); + if (!worker.readonly()) { + ssize_t r = image->write(m_offset, m_length, io->bufferlist()); + assertf(r >= 0, "id = %d, r = %d", id(), r); + } worker.remove_pending(io); } @@ -311,7 +317,7 @@ void OpenImageAction::perform(ActionCtx &worker) { librbd::Image *image = new librbd::Image(); librbd::RBD *rbd = worker.rbd(); int r; - if (m_readonly) { + if (m_readonly || worker.readonly()) { r = rbd->open_read_only(*worker.ioctx(), *image, m_name.c_str(), m_snap_name.c_str()); } else { r = rbd->open(*worker.ioctx(), *image, m_name.c_str(), m_snap_name.c_str()); diff --git a/src/rbd_replay/actions.hpp b/src/rbd_replay/actions.hpp index 9d728ac208658..14bfeeeed1e34 100644 --- a/src/rbd_replay/actions.hpp +++ b/src/rbd_replay/actions.hpp @@ -60,6 +60,8 @@ public: virtual void add_pending(boost::shared_ptr io) = 0; + virtual bool readonly() const = 0; + virtual void remove_pending(boost::shared_ptr io) = 0; virtual void set_action_complete(action_id_t id) = 0; diff --git a/src/rbd_replay/prep-for-replay.py b/src/rbd_replay/prep-for-replay.py index 5ae5782f7d1d4..ca8a1d18557d8 100755 --- a/src/rbd_replay/prep-for-replay.py +++ b/src/rbd_replay/prep-for-replay.py @@ -294,7 +294,6 @@ class Processor(object): ios = [] pendingIOs = {} limit = 100000000000 - ignoreWrites = True printOnRead = False printOnWrite = False threads = {} @@ -380,26 +379,24 @@ class Processor(object): if printOnRead: print str(thread.pendingIO) elif event.name == "librbd:write_enter": - if not ignoreWrites: - name = event["name"] - readid = event["id"] - offset = event["off"] - length = event["buf_len"] - imagectx = event["imagectx"] - ionum = self.nextID() - thread.pendingIO = WriteIO(ionum, ts, thread, thread.pendingIO, imagectx, [Extent(offset, length)]) - thread.pendingIO.addThreadCompletionDependencies(threads, self.recentCompletions) - thread.issuedIO(thread.pendingIO) - ios.append(thread.pendingIO) + name = event["name"] + readid = event["id"] + offset = event["off"] + length = event["buf_len"] + imagectx = event["imagectx"] + ionum = self.nextID() + thread.pendingIO = WriteIO(ionum, ts, thread, thread.pendingIO, imagectx, [Extent(offset, length)]) + thread.pendingIO.addThreadCompletionDependencies(threads, self.recentCompletions) + thread.issuedIO(thread.pendingIO) + ios.append(thread.pendingIO) elif event.name == "librbd:write_exit": - if not ignoreWrites: - thread.pendingIO.end_time = ts - completionIO = CompletionIO(ts, thread, thread.pendingIO) - thread.completedIO(completionIO) - ios.append(completionIO) - completed(completionIO) - if printOnRead: - print str(thread.pendingIO) + thread.pendingIO.end_time = ts + completionIO = CompletionIO(ts, thread, thread.pendingIO) + thread.completedIO(completionIO) + ios.append(completionIO) + completed(completionIO) + if printOnRead: + print str(thread.pendingIO) elif event.name == "librbd:aio_read_enter": name = event["name"] readid = event["id"] @@ -419,21 +416,20 @@ class Processor(object): if printOnRead: print str(thread.pendingIO) elif event.name == "librbd:aio_write_enter": - if not ignoreWrites: - name = event["name"] - writeid = event["id"] - offset = event["off"] - length = event["len"] - completion = event["completion"] - imagectx = event["imagectx"] - ionum = self.nextID() - thread.pendingIO = AioWriteIO(ionum, ts, thread, thread.pendingIO, imagectx, [Extent(offset, length)]) - thread.pendingIO.addThreadCompletionDependencies(threads, self.recentCompletions) - thread.issuedIO(thread.pendingIO) - ios.append(thread.pendingIO) - pendingIOs[completion] = thread.pendingIO - if printOnRead: - print str(thread.pendingIO) + name = event["name"] + writeid = event["id"] + offset = event["off"] + length = event["len"] + completion = event["completion"] + imagectx = event["imagectx"] + ionum = self.nextID() + thread.pendingIO = AioWriteIO(ionum, ts, thread, thread.pendingIO, imagectx, [Extent(offset, length)]) + thread.pendingIO.addThreadCompletionDependencies(threads, self.recentCompletions) + thread.issuedIO(thread.pendingIO) + ios.append(thread.pendingIO) + pendingIOs[completion] = thread.pendingIO + if printOnRead: + print str(thread.pendingIO) elif event.name == "librbd:aio_complete_enter": completion = event["completion"] retval = event["rval"] diff --git a/src/rbd_replay/rbd-replay.cc b/src/rbd_replay/rbd-replay.cc index 616a0276f7815..94be674662cae 100644 --- a/src/rbd_replay/rbd-replay.cc +++ b/src/rbd_replay/rbd-replay.cc @@ -35,8 +35,9 @@ static const char* get_remainder(const char *string, const char *prefix) { static void usage(const char* program) { cout << "Usage: " << program << " --conf= " << std::endl; - cout << "Options:" << endl; - cout << " --latency-multiplier Multiplies inter-request latencies. Default: 1" << endl; + cout << "Options:" << std::endl; + cout << " --latency-multiplier Multiplies inter-request latencies. Default: 1" << std::endl; + cout << " --read-only Only perform non-destructive operations." << std::endl; } int main(int argc, const char **argv) { @@ -48,6 +49,7 @@ int main(int argc, const char **argv) { std::vector::iterator i; float latency_multiplier = 1; + bool readonly = false; std::string val; std::ostringstream err; for (i = args.begin(); i != args.end(); ) { @@ -59,6 +61,8 @@ int main(int argc, const char **argv) { cerr << err.str() << std::endl; return 1; } + } else if (ceph_argparse_flag(args, i, "--read-only", (char*)NULL)) { + readonly = true; } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) { usage(argv[0]); return 0; @@ -85,5 +89,6 @@ int main(int argc, const char **argv) { unsigned int nthreads = boost::thread::hardware_concurrency(); Replayer replayer(2 * nthreads + 1); replayer.set_latency_multiplier(latency_multiplier); + replayer.set_readonly(readonly); replayer.run(replay_file); } -- 2.39.5