// vim: ts=8 sw=2 smarttab
#include "test/rbd_mirror/test_fixture.h"
+#include "include/stringify.h"
#include "include/rbd/librbd.hpp"
#include "journal/Journaler.h"
#include "librbd/AioImageRequestWQ.h"
#include "librbd/ExclusiveLock.h"
#include "librbd/ImageCtx.h"
#include "librbd/ImageState.h"
+#include "librbd/internal.h"
+#include "librbd/Operations.h"
#include "librbd/journal/Types.h"
#include "tools/rbd_mirror/ImageSync.h"
#include "tools/rbd_mirror/Threads.h"
void scribble(librbd::ImageCtx *image_ctx, int num_ops, size_t max_size)
{
+ max_size = MIN(image_ctx->size, max_size);
for (int i=0; i<num_ops; i++) {
uint64_t off = rand() % (image_ctx->size - max_size + 1);
uint64_t len = 1 + rand() % max_size;
str.c_str(), 0));
}
}
+
+ RWLock::RLocker owner_locker(image_ctx->owner_lock);
+ ASSERT_EQ(0, image_ctx->flush());
}
} // anonymous namespace
TEST_F(TestImageSync, Simple) {
scribble(m_remote_image_ctx, 10, 102400);
- {
- RWLock::RLocker owner_locker(m_remote_image_ctx->owner_lock);
- ASSERT_EQ(0, m_remote_image_ctx->flush());
- }
C_SaferCond ctx;
ImageSync<> *request = create_request(&ctx);
}
}
+TEST_F(TestImageSync, SnapshotStress) {
+ std::list<std::string> snap_names;
+
+ const int num_snaps = 4;
+ for (int idx = 0; idx <= num_snaps; ++idx) {
+ scribble(m_remote_image_ctx, 10, 102400);
+
+ librbd::NoOpProgressContext no_op_progress_ctx;
+ uint64_t size = 1 + rand() % m_image_size;
+ ASSERT_EQ(0, m_remote_image_ctx->operations->resize(size,
+ no_op_progress_ctx));
+ ASSERT_EQ(0, m_remote_image_ctx->state->refresh());
+
+ if (idx < num_snaps) {
+ snap_names.push_back("snap" + stringify(idx + 1));
+ ASSERT_EQ(0, create_snap(m_remote_image_ctx, snap_names.back().c_str(),
+ nullptr));
+ } else {
+ snap_names.push_back("");
+ }
+ }
+
+ C_SaferCond ctx;
+ ImageSync<> *request = create_request(&ctx);
+ request->start();
+ ASSERT_EQ(0, ctx.wait());
+
+ int64_t object_size = std::min<int64_t>(
+ m_remote_image_ctx->size, 1 << m_remote_image_ctx->order);
+ bufferlist read_remote_bl;
+ read_remote_bl.append(std::string(object_size, '1'));
+ bufferlist read_local_bl;
+ read_local_bl.append(std::string(object_size, '1'));
+
+ for (auto &snap_name : snap_names) {
+ uint64_t remote_size;
+ {
+ C_SaferCond ctx;
+ m_remote_image_ctx->state->snap_set(snap_name, &ctx);
+ ASSERT_EQ(0, ctx.wait());
+
+ RWLock::RLocker remote_snap_locker(m_remote_image_ctx->snap_lock);
+ remote_size = m_remote_image_ctx->get_image_size(
+ m_remote_image_ctx->snap_id);
+ }
+
+ uint64_t local_size;
+ {
+ C_SaferCond ctx;
+ m_local_image_ctx->state->snap_set(snap_name, &ctx);
+ ASSERT_EQ(0, ctx.wait());
+
+ RWLock::RLocker snap_locker(m_local_image_ctx->snap_lock);
+ local_size = m_local_image_ctx->get_image_size(
+ m_local_image_ctx->snap_id);
+ ASSERT_FALSE(m_local_image_ctx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID,
+ m_local_image_ctx->snap_lock));
+ }
+
+ ASSERT_EQ(remote_size, local_size);
+
+ for (uint64_t offset = 0; offset < remote_size; offset += object_size) {
+ ASSERT_LE(0, m_remote_image_ctx->aio_work_queue->read(
+ offset, object_size, read_remote_bl.c_str(), 0));
+ ASSERT_LE(0, m_local_image_ctx->aio_work_queue->read(
+ offset, object_size, read_local_bl.c_str(), 0));
+ ASSERT_TRUE(read_remote_bl.contents_equal(read_local_bl));
+ }
+ }
+}
+
} // namespace mirror
} // namespace rbd